IA32e四级分页表项值疑问:为何存在非零低位标志位
IA32e分页表项取值解析
问题背景
学习IA32e分页机制时,对示例中的PML4E、PDPTE、PDE取值存在疑问:
- 为何PML4E是
0x102007而非0x102000? - 为何PDPTE是
0x103003而非0x103000? - PDE中各类复杂取值的含义是什么?
示例代码(出自《一個64位操作系統的設計與實現》):
//======= 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
已知内核加载于物理地址0x100000,__PML4E、__PDPTE、__PDE分别位于内核加载地址偏移0x1000、0x2000、0x3000处,即它们的物理地址为:
- __PML4E:
0x100000 + 0x1000 = 0x101000 - __PDPTE:
0x100000 + 0x2000 = 0x102000 - __PDE:
0x100000 + 0x3000 = 0x103000
核心知识点:IA32e分页表项结构
IA32e模式下,PML4E、PDPTE、PDE(非大页模式)均为64位表项,结构如下:
| 比特位 | 含义 |
|---|---|
| 0 | P(Present):1表示表项有效,CPU可使用 |
| 1 | R/W(Read/Write):1表示可写,0表示只读 |
| 2 | U/S(User/Supervisor):1表示用户态可访问,0表示仅内核态可访问 |
| 3 | PWT(Page Write-Through):缓存写透模式控制 |
| 4 | PCD(Page Cache Disable):禁用缓存控制 |
| 5 | A(Accessed):1表示该表项被CPU访问过 |
| 6 | D(Dirty):仅页表项有效,表示页被写入过 |
| 7 | PS(Page Size):PDE中1表示2MB大页,0表示指向PT;PDPTE中1表示1GB大页 |
| 8 | G(Global):全局页,配合CR4.PGE使用 |
| 9-11 | AVL:自定义可用位 |
| 12-51 | PPN(Physical Page Number):物理页帧号,物理地址 = PPN << 12 |
逐个解析表项
1. PML4E:0x102007
拆解:0x102007 = 0x102000 + 0x7
- 物理地址部分:
0x102000,即0x102 << 12,对应__PDPTE的物理地址,说明该PML4E指向PDPT表的起始地址。 - 标志位部分:
0x7 = 0b111,对应:- P=1:表项有效
- R/W=1:可写
- U/S=1:用户态可访问
- 若取值为
0x102000,则P位为0,表项无效,CPU会抛出页错误,因此必须置位P标志。
2. PDPTE:0x103003
拆解:0x103003 = 0x103000 + 0x3
- 物理地址部分:
0x103000,即0x103 << 12,对应__PDE的物理地址,说明该PDPTE指向页目录(PD)的起始地址。 - 标志位部分:
0x3 = 0b11,对应:- P=1:表项有效
- R/W=1:可写
- U/S=0:仅内核态可访问
- 若取值为
0x103000,P位为0,表项无效,无法完成分页映射。
3. PDE取值解析
所有PDE的低12位均为0x83 = 0b10000011,先拆解标志位:
- P=1:表项有效
- R/W=1:可写
- U/S=0:仅内核态可访问
- PS=1:比特7为1,表示采用2MB大页模式,无需页表(PT)直接映射物理页
- 其他标志位(PWT、PCD、A、D、G)均为0
2MB大页的映射规则为:物理地址 = PPN << 21(2MB = 2^21字节),逐个分析关键PDE:
0x000083:PPN为0x0,物理地址 =0x0 << 21 = 0x0,映射虚拟地址0x0 ~ 0x1FFFFF到物理地址0x0 ~ 0x1FFFFF。0x200083:PPN为0x200(0x200000 >> 12),物理地址 =0x200 << 21 = 0x2000000,映射虚拟地址0x200000 ~ 0x3FFFFF到物理地址0x2000000 ~ 0x3FFFFF。0xe0000083(注释0x a00000):PPN为0xe0000(0xe0000000 >> 12),物理地址 =0xe0000 << 21 = 0x1C000000000,对应注释中的虚拟地址偏移0xA00000,映射到预留的硬件/设备内存区域。0xe0600083(注释0x1000000):PPN为0xe0600(0xe0600000 >>12),物理地址 =0xe0600 <<21 = 0x1C180000000,对应虚拟地址偏移0x1000000,映射到内核扩展区域。
其余PDE遵循相同规则,分别映射连续的2MB虚拟地址块到对应的物理地址块,未填充的499个表项表示暂不映射该区域。
内容的提问来源于stack exchange,提问作者Raymond
相关产品推荐
相关产品推荐

