3. 页表项结构详解:PTE 的典型字段
页表项(Page Table Entry, PTE)是虚拟内存映射的核心数据结构,每个 PTE 对应一个虚拟页到物理页的映射关系。PTE 中不仅包含物理页框号(PFN),还包含一组权限位和状态位,用于控制对该页的访问方式、缓存策略以及记录页面的使用状态。本章详细解析 PTE 的典型字段及其在操作系统内核中的实际作用。
3.1 PTE 整体结构概览
一个典型的 64 位 PTE 由高位到低位依次包含:保留位/软件可用位、物理页框号(PFN)、以及一组权限/状态标志位。下图展示了一个标准 64 位 PTE 的位域布局:
3.2 核心字段详解
3.2.1 Present 位(存在位)
Present 位(通常为 bit 0)指示该页表项对应的虚拟页是否当前驻留在物理内存中。这是 MMU 进行地址转换时检查的第一个条件。
- P=1:页在物理内存中,MMU 正常进行地址转换。
- P=0:页不在物理内存中(已被换出到磁盘,或尚未分配),MMU 触发缺页异常(Page Fault),由操作系统内核处理。
3.2.2 Read/Write 位(读写权限位)
R/W 位(通常为 bit 1)控制对该页的写操作权限。该位与处理器当前运行的特权级协同工作。
| R/W 位 | 处理器模式 | 允许操作 | 典型场景 |
|---|---|---|---|
| 0 | 用户态(Ring 3) | 只读 | 代码段、只读数据段 |
| 0 | 内核态(Ring 0) | 读写(x86 上内核可写只读页) | 内核访问用户代码段 |
| 1 | 用户态 | 读写 | 堆、栈、数据段 |
| 1 | 内核态 | 读写 | 内核数据区 |
3.2.3 User/Supervisor 位(用户/超级用户位)
U/S 位(通常为 bit 2)区分该页是用户态可访问还是仅内核态可访问。这是用户态与内核态隔离的关键机制。
- U/S=0(Supervisor):仅内核态(Ring 0/EL1/S-mode)可访问,用户态访问触发权限异常。
- U/S=1(User):用户态和内核态均可访问。
操作系统利用该位保护内核代码和数据段不被用户程序破坏。用户程序试图访问 U/S=0 的页时,MMU 直接拒绝并触发异常,无需软件干预。
3.2.4 Dirty 位(脏位)
Dirty 位(通常为 bit 6)由 MMU 硬件在第一次对该页执行写操作时自动置 1,表示该页的内容已被修改,与磁盘上的备份副本不一致。
- D=0:页未被写入过,内容与磁盘副本一致(干净页)。
- D=1:页已被写入,内容已修改(脏页),换出时必须写回磁盘。
3.2.5 Accessed 位(访问位)
Accessed 位(通常为 bit 5)由 MMU 硬件在第一次对该页进行读或写操作时自动置 1,表示该页最近被访问过。
操作系统利用 Accessed 位实现页面置换算法(如 Clock/第二次机会算法):
- 定期扫描页表,检查 Accessed 位。
- 若 A=1,则置为 0 并继续保留该页(给予“第二次机会”)。
- 若 A=0,则该页是候选换出页。
3.2.6 Page Frame Number(物理页框号)
PFN(也称为物理地址高位域)是 PTE 中最重要的地址字段,存储物理内存页框的基地址(高位)。MMU 将虚拟地址的页内偏移与 PFN 拼接,形成完整的物理地址。
PFN 的位宽取决于物理地址空间大小和页大小:
| 体系结构 | 页大小 | 物理地址宽度 | PFN 位宽 |
|---|---|---|---|
| x86-64(4KB 页) | 4 KB | 48 位(52 位扩展) | 36 位(40 位) |
| ARMv8-A(4KB 页) | 4 KB | 48 位 | 36 位 |
| RISC-V Sv39 | 4 KB | 56 位 | 44 位 |
3.3 字段组合与权限检查流程
MMU 在地址转换时,按固定顺序检查 PTE 字段,任何一步失败都会触发异常。下图展示了完整的权限检查流水线:
3.4 其他常见标志位
除上述核心字段外,不同体系结构还定义了若干辅助标志位:
| 标志位 | 典型位置 | 含义 | 典型用途 |
|---|---|---|---|
| PWT (Page Write-Through) | bit 3 | 页级写透缓存策略 | 控制该页的缓存写策略(透写/回写) |
| PCD (Page Cache Disable) | bit 4 | 页级缓存禁用 | 用于设备 I/O 内存映射页,禁止 CPU 缓存 |
| PAT (Page Attribute Table) | bit 7 | 页属性表索引(x86) | 扩展内存类型控制,与 PWT/PCD 组合使用 |
| G (Global) | bit 8 | 全局页标志 | 防止 TLB 刷新时清除该页(如内核空间常驻页) |
| NX (No-Execute) | bit 63 | 不可执行位 | 禁止在该页上执行代码(DEP/NX 保护) |
3.5 软件可用位与内核复用
PTE 的高位(如 x86-64 的 bits 63:52)通常被标记为“软件可用”(Software Available),操作系统内核可以自由写入自定义数据。常见复用场景包括:
- 页换出标记:当 P=0 时,PFN 字段被复用为交换文件偏移量,软件可用位存储换出状态。
- NUMA 节点 ID:记录该页所属的 NUMA 内存节点,用于内存亲和性调度。
- 引用计数/年龄:辅助页面置换算法记录页面的访问频率或老化信息。
- KSM (Kernel Same-page Merging) 标记:标识该页是否参与内核同页合并。
include/linux/pgtable.h 和体系结构相关的 arch/x86/include/asm/pgtable_types.h 中定义了 PTE 位域的操作宏,如 pte_present()、pte_mkdirty()、pte_wrprotect() 等。
3.6 本章小结
PTE 的每个字段都经过精心设计,在硬件效率与软件灵活性之间取得平衡:
- Present 位是地址转换的“开关”,控制页是否在内存中。
- R/W 和 U/S 位构成两级权限模型,实现用户态/内核态隔离与读写保护。
- Dirty 和 Accessed 位由硬件自动维护,为操作系统提供页使用状态信息,支撑换出策略。
- PFN 是映射的核心,将虚拟页绑定到物理页框。
- 辅助标志位(PWT、PCD、NX、G 等)提供细粒度的缓存、执行和 TLB 管理控制。