1. 内存管理基础:物理地址与虚拟地址的概念、MMU的作用、页表的基本结构
内存管理是操作系统内核最核心的子系统之一,而缺页异常(Page Fault)正是虚拟内存机制与物理内存管理之间的关键交互点。要深入理解缺页异常处理流程,必须先掌握三个基础概念:物理地址与虚拟地址、内存管理单元(MMU)以及页表。
1.1 物理地址与虚拟地址
物理地址(Physical Address, PA) 是硬件总线上的真实地址,直接对应内存芯片中的存储单元。CPU通过物理地址总线访问内存条上的数据。每个物理地址唯一标识一个字节的存储位置。
虚拟地址(Virtual Address, VA) 是程序视角看到的地址空间。每个进程拥有独立的虚拟地址空间(例如 32 位系统为 4GB,64 位系统更大),程序指令中使用的地址都是虚拟地址。虚拟地址必须经过转换才能变成物理地址。
核心认知: 虚拟地址是“假”的,物理地址是“真”的。进程永远活在虚拟世界里,MMU 负责把虚拟世界映射到物理现实。
| 对比维度 | 物理地址 | 虚拟地址 |
|---|---|---|
| 生成者 | 硬件总线 / 内存控制器 | CPU 指令 / 程序逻辑 |
| 空间大小 | 由物理内存容量决定(如 4GB) | 由 CPU 位宽决定(如 64 位为 16EB) |
| 进程隔离 | 全局共享,无隔离 | 每个进程独立,天然隔离 |
| 程序可见性 | 用户态程序不可见 | 用户态程序直接使用 |
| 连续性 | 物理上可能不连续(碎片) | 虚拟上连续,底层可离散 |
1.2 内存管理单元(MMU)的作用
MMU(Memory Management Unit) 是 CPU 内部的一个硬件模块,负责将虚拟地址实时转换为物理地址。它位于 CPU 核心与内存总线之间,是虚拟内存机制的硬件基石。
MMU 的核心职责
- 地址转换: 将 CPU 发出的虚拟地址,通过查页表转换为物理地址。
- 权限检查: 检查当前访问是否合法(读/写/执行权限、用户态/内核态权限)。
- 缺页触发: 当页表项无效(页不在物理内存中)时,MMU 触发缺页异常(Page Fault),交由内核处理。
- TLB 管理: 维护快表(Translation Lookaside Buffer),加速地址转换。
关键理解: MMU 是硬件加速器,页表是数据结构。MMU 每次访问内存都要查页表,TLB 缓存最近使用的页表项以减少性能开销。缺页异常是 MMU 发现页表项无效时向操作系统发出的“求救信号”。
1.3 页表的基本结构
页表(Page Table) 是操作系统维护的一种数据结构,用于记录虚拟页号(VPN)到物理页框号(PFN)的映射关系。每个进程拥有独立的页表,存储在物理内存中,由 MMU 硬件直接读取。
页表项(PTE)的核心字段
每个页表项(Page Table Entry, PTE)通常包含以下关键信息:
| 字段 | 位宽(典型) | 说明 |
|---|---|---|
| 物理页框号(PFN) | 20-52 位 | 映射到的物理内存页框起始地址 |
| Present 位(P) | 1 位 | 页是否在物理内存中(0 表示缺页) |
| Read/Write 位(R/W) | 1 位 | 是否允许写入(0 为只读) |
| User/Supervisor 位(U/S) | 1 位 | 用户态是否可访问(0 仅内核态) |
| Accessed 位(A) | 1 位 | 页是否被访问过(用于页面置换) |
| Dirty 位(D) | 1 位 | 页是否被写入过(用于回写) |
多级页表结构(以 x86_64 为例)
现代 64 位系统使用多级页表来节省内存。以 Linux 内核在 x86_64 架构上的 4 级页表为例:
- PGD(Page Global Directory) — 全局页目录
- P4D(Page 4th Directory) — 第 4 级页目录(某些配置下省略)
- PUD(Page Upper Directory) — 上层页目录
- PMD(Page Middle Directory) — 中间页目录
- PTE(Page Table Entry) — 页表项
注意: 多级页表的核心优势在于:对于大地址空间中未使用的部分,可以不为它们分配页表中间节点,从而大幅节省内存。缺页异常发生时,内核需要逐级遍历页表,找到或创建对应的页表项。
1.4 地址转换与缺页的触发条件
当 CPU 执行指令访问某个虚拟地址时,MMU 执行以下步骤:
- TLB 查找: 先在 TLB 中查找是否有该虚拟地址的转换缓存。如果命中(TLB hit),直接得到物理地址。
- 页表遍历: TLB 未命中(TLB miss)时,MMU 硬件自动遍历多级页表,逐级读取页表项。
- 权限检查: 检查 PTE 中的 U/S 位、R/W 位是否允许当前访问。
- Present 位判断: 检查 PTE 的 Present 位是否为 1。
- 若 Present=1:页在物理内存中,MMU 取出 PFN,拼接页内偏移,生成物理地址,访问内存。
- 若 Present=0:页不在物理内存中,MMU 触发 缺页异常(Page Fault),CPU 切换到内核态,执行缺页异常处理程序。
缺页异常的本质: 缺页异常不是错误,而是虚拟内存系统的正常工作机制。当进程访问的虚拟页尚未加载到物理内存、已被换出到磁盘、或是首次访问的匿名页时,MMU 通过缺页异常通知内核去“补上”这个页。内核在缺页处理中完成物理页分配、磁盘 I/O 读取、页表项填充等操作。
1.5 本章小结
- 物理地址 是硬件真实地址,虚拟地址 是进程视角的地址,两者通过 MMU 转换。
- MMU 是 CPU 内部的硬件单元,负责地址转换、权限检查和缺页触发。
- 页表 是存储在内存中的多级数据结构,每个进程独立拥有,页表项包含 PFN、Present 位、权限位等关键字段。
- 当页表项的 Present 位为 0 时,MMU 触发缺页异常,这是后续章节要深入分析的核心机制。