找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

157

积分

0

好友

19

主题
发表于 14 小时前 | 查看: 2| 回复: 0

实验原理与准备

在 Windows 操作系统中,理解内存管理机制是深入学习内核的关键。本次实验我们将手动解析一个内核数据结构——全局描述符表(GDT)的线性地址,通过拆解其 2-9-9-12 分页过程,直观地验证虚拟地址到物理地址的转换流程。

1. 获取目标地址与页目录基址

首先,我们需要找到 GDT 在内存中的线性地址。在 WinDbg 中,可以使用 gdtr 寄存器命令获取。

kd> r gdtr
GDT = 80b99000

接下来,需要获取页目录的物理基址,它存储在 CR3 寄存器中。由于内核空间在所有进程间共享,我们可以通过切换到任意用户进程上下文来获取其 CR3 值。

原理说明:用户进程的虚拟地址空间低 2GB 是独立的,但高 2GB 的内核空间对所有进程是共享映射的。因此,获取任意进程的 CR3 寄存器值,即可用于解析内核地址空间,包括 GDT、IDT、内核模块及驱动等。

使用以下命令列出进程并切换上下文:

!process 0 0
.process /p 7f21c4a0  // 切换至任意进程上下文,例如 EPROCESS 地址为 7f21c4a0

切换后,CR3 寄存器中存储的就是该进程页目录的物理地址。

手动拆解 2-9-9-12 分页过程

我们获得了 GDT 的线性地址:0x80b99000。接下来,按照 2-9-9-12 的模式将其拆分。

地址二进制拆分
0x80b99000 = 1000 0000 1011 1001 1001 0000 0000 0000
按 2-9-9-12 划分后:

  • 第1个2位(PDPT索引):10 -> 0x2
  • 第2个9位(PDE索引):000000101 -> 0x5
  • 第3个9位(PTE索引):110011001 -> 0x199
  • 第4个12位(页内偏移):000000000000 -> 0x0

2.1 获取页目录指针表项(PDPTE)

PDPT 的基址由 CR3 寄存器直接给出。计算第一个索引:

PDPT_index = 0x2

使用 WinDbg 命令查询对应的 PDPTE:

!dq (cr3 + PDPT_index * 8)
!dq (0x7f21c4a0 + 0x2*8)  // 假设此时 cr3 值为 0x7f21c4a0

命令执行后,我们得到:

PDPTE = 00000000`545cf801

PDPTE查询结果示意图
上图为 WinDbg 中查询 PDPTE 的输出结果,其中包含了下一级页表的物理地址。

2.2 获取页目录项(PDE)

从上一步得到的 PDPTE 中,提取出页目录的物理基址(低 12 位为属性位,需清零)。然后计算 PDE 索引:

PDE_index = 0x5
PDPT_Base = 00000000`545cf000  // 545cf801 & ~0xFFF

查询对应的 PDE:

!dq (PDPT_Base + PDE_index * 8)
!dq (00000000`545cf000 + 0x5*8)

命令执行后,我们得到:

PDE = 00000000`00193063

PDE查询结果示意图
此步骤通过 PDE 定位到了页表(Page Table)的物理地址。

2.3 获取页表项(PTE)

同样,从 PDE 中提取页表的物理基址,然后计算 PTE 索引:

PTE_index = 0x199
PDE_Base = 00000000`00193000  // 00193063 & ~0xFFF

查询对应的 PTE:

!dq (PDE_Base + PTE_index * 8)
!dq (00000000`00193000 + 0x199*8)

命令执行后,我们得到:

PTE = 00000000`00b99163

PTE查询结果示意图
页表项(PTE)中包含了目标物理页帧的地址。

2.4 获取最终物理地址并验证

从 PTE 中提取出 4KB 物理页的基址,加上页内偏移,即可得到最终的物理地址。

PTE_Base = 00000000`00b99000  // 00b99163 & ~0xFFF
offset = 0x0

查询该物理地址的内容:

!dq (00000000`00b99000 + 0x0)

最终物理页内容对比
最终查询到的物理页内容(上图)与直接用线性地址 dq 80b99000 查询 GDT 表的结果完全一致,成功验证了整个分页转换过程。

扩展探讨:为什么是 2-9-9-12?

一个常见的疑问是:为了实现大于 4GB 的物理内存支持,为什么 Intel 选择了 2-9-9-12 分页,而不是在原有的 10-10-12 模式上简单地将 PDE/PTE 扩展为 8 字节?

核心原因在于硬件兼容性与改动成本
理论上,10-10-12 格式通过扩展表项宽度也能支持更大物理内存。但这需要同步修改 CPU 的页表格式解释逻辑、TLB 结构、CR3 寄存器规则以及地址步进计算等一系列底层硬件机制,改动量巨大。

2-9-9-12(PAE 模式) 的设计巧妙之处在于:

  1. 最小化改动:它在 CR3 之上增加了一层 PDPT(页目录指针表),仅通过引入一个 4 项的小型表就实现了 64 位物理地址的索引,对原有分页结构的冲击相对较小。
  2. 保持兼容:操作系统可以选择是否启用 PAE。未启用时,系统仍以传统模式运行,保证了老系统的兼容性。
  3. 自然扩展:这种结构为后来 64 位时代的 4 级分页(PML4)乃至 5 级分页奠定了设计基础,是理解现代 网络/系统 内存管理机制的重要一环。

深入理解分页机制,对于进行内核开发、云原生/IaaS 底层调优或安全研究都至关重要。




上一篇:AI硬件大脑新范式:14年OS经验与多传感器耳机的系统级软件定义
下一篇:SK海力士预测DRAM短缺至2028年,DDR5、HBM与消费级内存供应承压
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-17 16:30 , Processed in 0.179889 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表