Linux页表与ARM硬件页表

早期Linux内核是基于x86体系结构设计的,x86页表中有3个标志位是ARM32硬件页表项没有的。
PTE_DIRTY:cpu在写操作时会设置该标志位,表示对应页面被写过,为脏页。
PTE_YOUNG:CPU访问该页时会设置该标志位。在页面换出时,如果该标志位位置了,说明该页刚被访问过,页面是young的,不适合把该页换出,同时清除该标志位。
PTE_PRESENT:表示页在内存中。

 

针对这种情况,Linux维护了一份Linux版本的页表,用于模拟这些标志位。由于一个页面是4KB大小,一级PGD页表项对应256个pte,256*sizeof(u32)占用1KB,Linux版本pte也需要占用1KB,所以Linux创建二级页表时,以两个pgd页表项为单位,申请1个page存放对应的linux版本pte和硬件pte。前2KB存放linux版本页表,后2KB存放硬件页表。存放地址如下。

 *    pgd             pte
 * |        |
 * +--------+
 * |        |       +------------+ +0
 * +- - - - +       | Linux pt 0 |
 * |        |       +------------+ +1024
 * +--------+ +0    | Linux pt 1 |
 * |        |-----> +------------+ +2048
 * +- - - - + +4    |  h/w pt 0  |
 * |        |-----> +------------+ +3072
 * +--------+ +8    |  h/w pt 1  |
 * |        |       +------------+ +4096

左边是一级页表项 block,而右边是一个 page 中包含的四个(两对)二级页表 block 项,硬件页表项放在软件页表项 +2048 处。

#define PMD_SHIFT       21

从硬件定义来看,每个 pte block 应该是 1M,SHIFT 值应该是 20,但是软件上的处理为:将两个 pte block 放在一个页面中,因此每个 PGD 占用 8 bytes,而 PMD = PGD,因此 PMD 也就相当于两个 pte block,两个页面也就是 2M,SHIFT 为 21。

 

posted @ 2023-06-03 11:59  流水灯  阅读(145)  评论(0编辑  收藏  举报