3. ARMv7-A L1页表项格式:一级页表描述符结构

ARMv7-A 架构使用两级或三级页表实现虚拟地址到物理地址的转换。L1(一级)页表是整个转换过程的入口点,其描述符格式直接决定了地址映射的粒度与后续查找路径。本章详细解析一级页表描述符的三种类型:节描述符、粗页表描述符和细页表描述符。

3.1 一级页表描述符通用结构

一级页表(L1 Translation Table)包含 4096 个描述符项,每个描述符占用 32 位(4 字节)。虚拟地址的高 12 位(bits[31:20])作为索引,从 L1 页表中选取对应的描述符。描述符的最低 2 位(bits[1:0])用于区分描述符类型:

bits[1:0] 描述符类型 映射粒度 后续查找
0b00 无效(Fault) — 产生转换错误
0b01 粗页表描述符(Coarse Page Table) 4KB / 64KB / 1MB 指向二级粗页表
0b10 节描述符(Section) 1MB 直接映射(无二级表)
0b11 细页表描述符(Fine Page Table) 4KB / 64KB / 1MB / 16MB 指向二级细页表
关键提示: bits[1:0] = 0b10 是节描述符,直接完成 1MB 块映射,无需二级页表,是性能最优的映射方式。粗页表和细页表描述符则需要进一步查找二级页表。

3.2 节描述符(Section Descriptor)

节描述符用于将 1MB 的虚拟地址块直接映射到物理地址块。当 bits[1:0] = 0b10 时,描述符格式如下:

31                    20 19  18  17  16  15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
+-------------------------------------------------------------------------------------------------------+
| 节基地址[31:20]        | 0 | 0 | 0 | nG | S | APX | TEX[2:0] | AP[2:1] | 0 | 0 | 0 | C | B | 1 | 0 |
+-------------------------------------------------------------------------------------------------------+
位域 宽度 说明
[31:20] 12 bits 物理地址高位(物理节基地址),与虚拟地址低 20 位拼接形成 1MB 物理地址
[19] 1 bit SBZ(应为 0),架构保留
[18:17] 2 bits 域(Domain),用于访问控制检查
[16] 1 bit nG(非全局位),用于 TLB 标记
[15] 1 bit S(可共享位),用于缓存一致性
[14] 1 bit APX(访问权限扩展),与 AP 共同决定权限
[13:11] 3 bits TEX(类型扩展),与 C/B 共同决定内存类型和缓存策略
[10:9] 2 bits AP(访问权限),控制读写权限
[8:5] 4 bits SBZ(应为 0)
[4] 1 bit C(缓存位),与 TEX/B 配合
[3] 1 bit B(缓冲位),与 TEX/C 配合
[1:0] 2 bits 类型标识 = 0b10
节映射示例: 若虚拟地址 0x10000000 对应的 L1 描述符中节基地址为 0x20000,则虚拟地址 0x10000000~0x100FFFFF 映射到物理地址 0x20000000~0x200FFFFF。虚拟地址的低 20 位直接作为物理地址的低 20 位偏移。
节描述符映射流程 虚拟地址 L1索引[31:20] 偏移[19:0] L1页表(4096项) 节描述符(1MB) 物理地址(1MB块) 基地址[31:20] 偏移[19:0] 节描述符特点 • 映射粒度:1MB,适合大块连续内存映射(如内核、设备寄存器) • 无需二级页表,TLB 开销最小,转换延迟最低 • 支持域检查、访问权限、内存属性配置

3.3 粗页表描述符(Coarse Page Table Descriptor)

粗页表描述符指向一个二级粗页表(Coarse Page Table),该二级表包含 256 个描述符项,每个项对应 4KB 页面。当 bits[1:0] = 0b01 时,描述符格式如下:

31                    10   9   8   7   6   5   4   3   2   1   0
+-------------------------------------------------------------------+
| 粗页表基地址[31:10]      | 域[2:0] | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
+-------------------------------------------------------------------+
位域 宽度 说明
[31:10] 22 bits 二级粗页表的物理基地址(1KB 对齐)
[9:7] 3 bits 域(Domain),用于访问控制检查
[6:2] 5 bits SBZ(应为 0)
[1:0] 2 bits 类型标识 = 0b01
注意: 粗页表描述符的基地址必须 1KB 对齐(即 bits[9:0] 为 0)。二级粗页表的大小为 1KB(256 项 × 4 字节),因此整个二级表恰好占用 1KB 空间。

粗页表描述符的二级查找流程:

  1. 从 L1 描述符中提取粗页表基地址(bits[31:10]),拼接 10 位 0 得到二级表物理地址。
  2. 虚拟地址的 bits[19:12](8 位)作为索引,从二级粗页表中选取对应的二级描述符。
  3. 二级描述符可以是 4KB 页描述符、64KB 大页描述符或无效描述符。
粗页表描述符二级查找流程 L1粗页表描述符 基地址[31:10] + 10'b0 二级粗页表(256项) 索引:VA[19:12] 二级页/大页描述符 粗页表特点 • 二级表大小:1KB(256项 × 4字节) • 支持4KB页和64KB大页映射 • 适合需要细粒度映射的场景

3.4 细页表描述符(Fine Page Table Descriptor)

细页表描述符指向一个二级细页表(Fine Page Table),该二级表包含 1024 个描述符项,每个项对应 1KB 页面。当 bits[1:0] = 0b11 时,描述符格式如下:

31                    12  11  10   9   8   7   6   5   4   3   2   1   0
+-----------------------------------------------------------------------+
| 细页表基地址[31:12]      | 0 | 域[2:0] | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
+-----------------------------------------------------------------------+
位域 宽度 说明
[31:12] 20 bits 二级细页表的物理基地址(4KB 对齐)
[11] 1 bit SBZ(应为 0)
[10:8] 3 bits 域(Domain),用于访问控制检查
[7:2] 6 bits SBZ(应为 0)
[1:0] 2 bits 类型标识 = 0b11
细页表 vs 粗页表: 细页表支持 1KB 最小页面粒度,二级表大小为 4KB(1024项 × 4字节),基地址要求 4KB 对齐。粗页表支持 4KB 最小粒度,二级表大小为 1KB,基地址要求 1KB 对齐。细页表提供更细的映射粒度,但页表开销更大。

3.5 三种描述符对比总结

特性 节描述符 粗页表描述符 细页表描述符
bits[1:0] 0b10 0b01 0b11
映射粒度 1MB(直接映射) 4KB / 64KB(二级表) 1KB / 4KB / 64KB / 16MB(二级表)
二级表大小 无 1KB(256项) 4KB(1024项)
基地址对齐 1MB 1KB 4KB
页表开销 最小(仅L1表) 中等(L1 + 1KB二级表) 最大(L1 + 4KB二级表)
适用场景 大块连续内存(内核、设备) 通用进程地址空间 需要1KB细粒度映射(嵌入式)
TLB效率 最高(单级查找) 中等(两级查找) 较低(两级查找,项多)
三种L1描述符结构对比 节描述符(0b10) 1MB 直接映射 粗页表描述符(0b01) 二级表 → 4KB/64KB 细页表描述符(0b11) 二级表 → 1KB/4KB/64KB 选择建议 • 节描述符:性能最优,适合映射内核、设备寄存器、大块连续物理内存 • 粗页表描述符:平衡灵活性与开销,是Linux内核默认的L1描述符类型 • 细页表描述符:粒度最细,但页表开销大,ARMv7-A中已不推荐使用
实践建议: 在 ARMv7-A 的 Linux 内核实现中,默认使用粗页表描述符(L1类型=0b01),配合二级4KB页表。节描述符常用于线性映射区域(如内核直接映射区)。细页表描述符由于页表开销大且硬件支持有限,在实际系统中很少使用。