不了解 IA32E 4 级分页



我最近研究了IA32e分页,虽然我知道它是如何工作的,但是当我遇到一个真实的例子时,我无法理解每个条目中的值表示什么。

我已经阅读了手册,它告诉我有几个标志位需要设置,我试图将以下示例中的PML4E, PDPTE和PDE的值分解为手册上写的格式,但结果似乎是错误的。

//=======   init page
.align 8
.org    0x1000
__PML4E:
.quad   0x102007
.fill   255,8,0
.quad   0x102007
.fill   255,8,0
.org    0x2000
__PDPTE:

.quad   0x103003
.fill   511,8,0
.org    0x3000
__PDE:
.quad   0x000083    
.quad   0x200083
.quad   0x400083
.quad   0x600083
.quad   0x800083
.quad   0xe0000083      /*0x a00000*/
.quad   0xe0200083
.quad   0xe0400083
.quad   0xe0600083      /*0x1000000*/
.quad   0xe0800083
.quad   0xe0a00083
.quad   0xe0c00083
.quad   0xe0e00083
.fill   499,8,0

代码来自书<<64位操作系统的设计与实现。代码在这个GitHub存储库

中可用。内核在内存0x100000处加载;__PML4E、__PDPTE和__PDE相对于内核加载位置存储在偏移量0x1000、0x2000、0x3000处

但我不能理解的是,为什么有0x102007而不是0x102000, 0x103003而不是0x103000,以及__PDE中复杂的值。

值为0x102007的PML4E是0x102000 + FLAG_PRESENT + FLAG_WRITE + FLAG_USER,它将该表项控制的512gb区域设置为可写且可访问的CPL &gt代码;0(并标记条目存在)。

值为0x103003的PDPTE是0x102000 + FLAG_PRESENT + FLAG_WRITE,它将该表项控制的1GiB区域设置为可写,但不能被带有CPL &gt的代码访问;0(并标记条目存在)。

值为0x000083的PDE是0x000000 + FLAG_PRESENT + FLAG_WRITE + FLAG_PAGESIZE,这使得PDE直接映射一个可写的2MiB页面,该页面不能被CPL &gt代码访问;0(并标记条目存在)。

假设设置了分页,这些分页结构将创建以下内存映射:

0               -  10MiB            Identity mapped as writable for the kernel
10MiB           -  26MiB            Mapped to 0xe0000000 as writable for the kernel
26MiB           -  1GiB             Not mapped
1GiB            -  512GiB           Not mapped
512GiB          -  64TiB            Not mapped
64TiB           -  64TiB + 512GiB   Alias to range 0 - 512GiB
64TiB + 512GiB  -  256TiB           Not mapped 

最新更新