2. 页表基础概念:PTE、描述符、层级与页大小

页表是操作系统与 MMU(内存管理单元)之间最核心的契约。ARM64 架构采用多级页表设计,将虚拟地址到物理地址的映射拆解为多个查找阶段。理解页表项(PTE)、描述符格式、层级结构以及页大小,是调试页表配置和分析性能的前提。

核心观点:ARM64 的页表不是一张大表,而是一棵由多级表构成的树。每一级表项要么指向下一级表的基地址,要么直接指向物理页帧。这种设计在节省内存的同时,也引入了多级遍历的开销。

2.1 页表项(PTE)与描述符

页表项(Page Table Entry, PTE)是页表中的最小单元,通常为 8 字节(64 位)。ARM64 将 PTE 的内容称为描述符(Descriptor),根据其类型决定 MMU 的行为。

2.1.1 描述符类型

ARM64 页表描述符分为三种类型,由最低两位(bit[1:0])标识:

bit[1:0] 描述符类型 含义
00 Invalid(无效) 该表项未映射,访问将触发缺页异常
01 Table(表描述符) 指向下一级页表的基地址(仅用于 L0/L1/L2)
10 Block(块描述符) 直接映射一个连续的大内存块(仅用于 L1/L2/L3)
11 Page(页描述符) 映射一个标准页(仅用于 L3)
调试要点:在调试页表时,首先检查描述符的 bit[1:0]。如果看到 00,说明该映射未建立;如果看到 01,说明当前表项是跳转节点,需要继续向下查找。

2.1.2 PTE 关键字段(以 4KB 页为例)

一个典型的 L3 页描述符(Page Descriptor)包含以下关键位域:

63      48  47    12  11  10   9   8   7   6   5   4   3   2   1   0
+----------+--------+---+---+---+---+---+---+---+---+---+---+---+---+
|  UpperAttr|  PA[47:12] |   |   |   |   |   |   |   |   |   |   |   |
|  (IGNORED)|  (物理页帧)  |   |   |   |   |   |   |   |   |   |   |   |
+----------+--------+---+---+---+---+---+---+---+---+---+---+---+---+
                            |   |   |   |   |   |   |   |   |   |   |
                            |   |   |   |   |   |   |   |   |   |   +-- Descriptor Type (11)
                            |   |   |   |   |   |   |   |   |   +------ Non-Secure
                            |   |   |   |   |   |   |   |   +---------- Access Flag
                            |   |   |   |   |   |   |   +-------------- Shareability
                            |   |   |   |   |   |   +------------------ AF (Access Flag)
                            |   |   |   |   |   +---------------------- nG (non-global)
                            |   |   |   |   +-------------------------- AttrIndx[0]
                            |   |   |   +------------------------------ AttrIndx[1]
                            |   |   +---------------------------------- NS (Non-Secure)
                            |   +-------------------------------------- AP[1] (权限)
                            +------------------------------------------ AP[0] (权限)
  • PA[47:12]:物理页帧号(PFN),共 36 位,指向 4KB 对齐的物理页。
  • Descriptor Type:bit[1:0] = 11,表示 L3 页描述符。
  • AP[2:1]:访问权限控制(读/写/特权级)。
  • AF:访问标志位,MMU 在首次访问时会硬件置位,用于页表遍历加速。
  • AttrIndx[2:0]:指向 MAIR(内存属性间接寄存器)的索引,定义缓存策略。

2.2 页表层级结构(Level 0/1/2/3)

ARM64 支持最多 4 级页表(L0 ~ L3),具体级数由虚拟地址宽度和页大小共同决定。以最常见的 48 位虚拟地址 + 4KB 页 配置为例,地址翻译过程如下:

  1. L0 索引:VA[47:39] → 查找 L0 表(Table Descriptor),得到 L1 表基址。
  2. L1 索引:VA[38:30] → 查找 L1 表,得到 L2 表基址。
  3. L2 索引:VA[29:21] → 查找 L2 表,得到 L3 表基址。
  4. L3 索引:VA[20:12] → 查找 L3 表(Page Descriptor),得到物理页帧号。
  5. 页内偏移:VA[11:0] → 加上物理页帧基址,得到最终物理地址。
性能陷阱:每次地址翻译都需要 4 次内存访问(L0→L1→L2→L3)。TLB(Translation Lookaside Buffer)的存在就是为了缓存最近使用的翻译结果,避免重复遍历。如果页表层级过多或 TLB 命中率低,翻译延迟会显著增加。
ARM64 4级页表地址翻译流程(48位VA + 4KB页) ARM64 4级页表地址翻译流程(48位VA + 4KB页) 虚拟地址 VA[47:0] L0 索引 [47:39] L1 索引 [38:30] L2 索引 [29:21] L3 索引 [20:12] 偏移 [11:0] L0 页表 Table Descriptor L1 页表 Table Descriptor L2 页表 Table Descriptor L3 页表 Page Descriptor 物理页帧 PA[47:12] + 偏移 说明: 每级页表通过 Table Descriptor 指向下一级基址。 L3 页表最终通过 Page Descriptor 输出物理页帧号。

2.3 页大小与层级组合

ARM64 支持三种标准页大小:4KB、16KB 和 64KB。页大小直接影响页表级数、TLB 覆盖范围和内存碎片。下表总结了不同配置下的层级关系:

页大小 虚拟地址宽度 页表级数 L0 索引 L1 索引 L2 索引 L3 索引 页内偏移
4KB 48 位 4 级 [47:39] [38:30] [29:21] [20:12] [11:0]
16KB 48 位 4 级 [47:47] [46:36] [35:25] [24:14] [13:0]
64KB 48 位 3 级 — [47:42] [41:29] [28:16] [15:0]
4KB 39 位 3 级 — [38:30] [29:21] [20:12] [11:0]
64KB 42 位 3 级 — [41:29] [28:16] — [15:0]
工程选择建议:
  • 4KB 页:最通用,粒度细,适合需要精细内存保护的场景(如容器、虚拟化)。但页表级数多,TLB 压力大。
  • 64KB 页:TLB 覆盖范围大,适合大内存、高性能计算场景。但内存碎片更严重,且需要硬件和操作系统同时支持。
  • 16KB 页:介于两者之间,在移动端和某些服务器场景中有使用。

2.4 多级页表的性能权衡

多级页表的核心优势是按需分配:只有实际使用的虚拟地址范围才需要分配页表。但代价是翻译延迟和TLB 缺失开销。

多级页表性能权衡 多级页表性能权衡 优势 • 按需分配页表,节省内存 • 支持大虚拟地址空间(48位) • 支持大页(Block Descriptor) • 进程切换时只需切换根表指针 • 细粒度权限控制(每页) 劣势 • 多次内存访问增加翻译延迟 • TLB 缺失时开销大(4次访问) • 页表本身占用内存(4KB/表) • 页表遍历增加功耗 • 多级索引计算增加硬件复杂度
性能分析切入点:在调试页表性能时,重点关注以下指标:
  • TLB 缺失率:通过 PMU(性能监视单元)计数器读取。
  • 页表遍历次数:每次 TLB 缺失都会触发硬件页表遍历。
  • 大页使用比例:使用 Block Descriptor(如 2MB/1GB 大页)可以减少页表级数。
  • 页表缓存(PTW):某些 ARM64 实现有专门的页表遍历缓存。

2.5 本章小结

  • PTE 是页表的基本单元,描述符类型决定是跳转(Table)还是映射(Block/Page)。
  • ARM64 页表 支持 L0~L3 共 4 级,具体级数由 VA 宽度和页大小决定。
  • 页大小 可选 4KB/16KB/64KB,影响 TLB 覆盖范围和内存碎片。
  • 多级页表 在节省内存的同时引入了翻译延迟,性能分析需关注 TLB 缺失率和页表遍历开销。