分页机制

先说说最基本的未开启PAE时的10-10-12分页 (PDE为页表地址,PTE为物理页地址)

CR3存有页目录表的物理地址,页目录表有1024项,存有页表的物理地址,每张页表有1024项,存有物理页的地址。由于系统的内存通常都是按照4kb对齐,所以页目录表和页表中的地址的低12位都是保留位,另做他用。

但其实上面这种结构方式是错误的,正确的的结构方式是这样的:

其实页目录表(PDT)本不存在,是抽象出来的.

  • 页表被映射到了从0xC0000000到0xC03FFFFF的4M地址空间

  • 在这1024个表中有一张特殊的表:页目录表

  • 页目录被映射到了0xC0300000开始处的4K地址空间

所以我们就能根据线性地址计算所在物理页地址

访问页目录表的公式: 0xC0300000 + PDI*4

访问页表的公式: 0xC0000000 + PDI*4096 + PTI*4

(PDI为页目录表偏移是线性地址高10位,PTI为页表偏移是线性地址的高12-21位)

但本次实验环境 win7 x86 默认分页方式为 2-9-9-12分页,四页式。

根据 CR3 找到 Page Directory Pointer Table
根据一级索引在 Page Directory Pointer Table 中查询到 Page Directory
根据二级索引在 Page Directory 中查询到 Page Table
根据三级索引在 Page Table 中查询到普通 4KB 物理页
在物理页中查找第四段偏移。

如下图:

根据以上描述,第一段索引其实就是 Page Directory Pointer Table(PDPT) 这张表的索引。 下面的彩图也许能帮助你理解。

这种分页方式不同于三段式,三段式分页最大只支持4GB内存寻址,intel把处理器的管脚数从32位增加到36个满足了更大的内存需求。

三段式分页中的 PDE 和 PTE 都是 4 字节,无论是 PDT 还是 PTT 都有1024个表项。而PAE分页中,PDPT只有 4 个表项,PDT 和 PTT 有 512 个表项,PDPTE、PDE、PTE 的大小是 8 字节。 PDPT 表一共占用 32 字节,PDT 、PTT 表仍然占用 4KB 的物理页。

这里列出它的PTE结构图:

PTE结构的低12位同三段式分页仍然是属性,唯一的区别就是,Page Base Address 由原来的 20 位变成了现在的 24 位,相对以前扩展了 4 位。注意从 36-63 位这28位是保留位,不可用的。

这意味着,PTE 可以索引到的物理页页号由原来的 2的20次方 变成现在的 2的24次方,同样的,一个物理页大小是 4KB,那么PTE可以索引到的最大物理地址将会达到 2^24 * 2^12 =64GB。

其实,PAE 所做的事情,只是把线性地址的 4GB 虚拟空间打散到了物理地址的64 GB 空间中。

形如图:

这里就直接给出该分页模式下 PDE 和 PTE 地址计算公式

addr 存放的是线性地址

pPDE = (int*)(0xc0600000 + ((addr >> 18) & 0x3ff8));
pPTE = (int*)(0xc0000000 + ((addr >> 9) & 0x7ffff8));