4、页表配置寄存器详解:TCR_EL1、MAIR_EL1、SCTLR_EL1 中与 MMU/页表相关的位域
ARMv8-A 体系结构中,MMU 的初始化与页表配置依赖于三个核心系统寄存器:TCR_EL1(Translation Control Register)、MAIR_EL1(Memory Attribute Indirection Register)和 SCTLR_EL1(System Control Register)。这三个寄存器共同决定了虚拟地址到物理地址的翻译规则、内存属性以及 MMU 的全局使能状态。本章将逐一拆解其中与页表配置直接相关的位域,并结合实际调试场景进行说明。
4.1 TCR_EL1:翻译控制寄存器
TCR_EL1 控制 EL1 阶段(Stage 1)的地址翻译参数,包括输入地址大小、输出物理地址大小、页粒度、缓存策略以及 ASID 管理。其关键位域如下表所示:
| 位域 | 名称 | 功能描述 | 典型配置值 |
|---|---|---|---|
| [37:32] | IPS | 中间物理地址大小(Intermediate Physical Address Size),决定 PA 范围 | 0b101(48位,256TB) |
| [31:30] | TG1 | TTBR1 粒度的编码(0=4KB,1=64KB,2=16KB) | 0b00(4KB) |
| [29:28] | SH1 | TTBR1 对应的共享属性(00=非共享,01=预留,10=外设共享,11=内部共享) | 0b11(内部共享) |
| [27:26] | ORGN1 | TTBR1 对应的外部缓存策略(00=非缓存,01=写通,10=写回,11=写回+分配) | 0b11(写回+读分配写分配) |
| [25:24] | IRGN1 | TTBR1 对应的内部缓存策略(编码同 ORGN1) | 0b11(写回+分配) |
| [23:22] | EPD1 | TTBR1 页表遍历使能(0=使能,1=禁止) | 0b0(使能) |
| [21:16] | T1SZ | TTBR1 区域地址空间大小(64 - T1SZ = 有效虚拟地址位数) | 0b100000(32位,即 64-32=32) |
| [15:14] | TG0 | TTBR0 粒度的编码(同 TG1) | 0b00(4KB) |
| [13:12] | SH0 | TTBR0 对应的共享属性 | 0b11(内部共享) |
| [11:10] | ORGN0 | TTBR0 对应的外部缓存策略 | 0b11(写回+分配) |
| [9:8] | IRGN0 | TTBR0 对应的内部缓存策略 | 0b11(写回+分配) |
| [7] | EPD0 | TTBR0 页表遍历使能 | 0b0(使能) |
| [5:0] | T0SZ | TTBR0 区域地址空间大小(同 T1SZ 编码) | 0b100000(32位) |
下图展示了 TCR_EL1 中 T0SZ/T1SZ 如何决定虚拟地址的翻译范围,以及 TG0/TG1 如何影响页表层级数:
4.2 MAIR_EL1:内存属性间接寄存器
MAIR_EL1 用于定义最多 8 个内存属性区域(Attribute Index 0~7),每个区域占用 8 位,编码了该区域的类型(Normal/Device)以及缓存策略(Write-Back/Write-Through/Non-Cacheable)。页表描述符中的 AttrIndx[2:0] 字段直接索引 MAIR_EL1 中的属性配置。
MAIR_EL1 的 64 位布局如下:
| 位域 | 索引 | 典型配置值 | 内存属性含义 |
|---|---|---|---|
| [63:56] | Attr7 | 0xFF | Normal Memory, Write-Back, Read/Write Allocate |
| [55:48] | Attr6 | 0x44 | Device-nGnRE(非聚集、非重排、提前写确认) |
| [47:40] | Attr5 | 0x00 | Device-nGnRnE(最严格的 Device 类型) |
| [39:32] | Attr4 | 0xBB | Normal Memory, Write-Back, 不分配 |
| [31:24] | Attr3 | 0x88 | Normal Memory, Non-Cacheable |
| [23:16] | Attr2 | 0x00 | (未使用) |
| [15:8] | Attr1 | 0x00 | (未使用) |
| [7:0] | Attr0 | 0x00 | (未使用) |
下图展示了页表描述符如何通过 AttrIndx 字段索引 MAIR_EL1 中的属性配置:
4.3 SCTLR_EL1:系统控制寄存器中的 MMU 相关位域
SCTLR_EL1 是系统控制的核心寄存器,其中与 MMU 和页表直接相关的位域包括 M、C、I、WXN、UWXN 等。这些位域控制 MMU 的全局使能、缓存策略以及内存访问权限。
| 位域 | 名称 | 功能描述 | 典型配置 |
|---|---|---|---|
| [0] | M | MMU 使能位(0=禁用,1=使能) | 1(使能) |
| [2] | C | 数据缓存使能(0=禁用,1=使能) | 1(使能) |
| [3] | SA | 栈对齐检查(0=禁用,1=使能) | 0(禁用) |
| [12] | I | 指令缓存使能(0=禁用,1=使能) | 1(使能) |
| [19] | WXN | 写权限不可执行(0=允许,1=禁止可写页面执行) | 1(禁止) |
| [21] | UWXN | 用户写权限不可执行(0=允许,1=禁止用户可写页面执行) | 1(禁止) |
| [25] | EE | 异常字节序(0=小端,1=大端) | 0(小端) |
| [28] | nTWE | 陷阱 WFE(0=不陷阱,1=陷阱) | 0(不陷阱) |
| [29] | nTWI | 陷阱 WFI(0=不陷阱,1=陷阱) | 0(不陷阱) |
下图展示了 SCTLR_EL1 中 MMU 相关位域如何协同工作:
4.4 寄存器配置的典型初始化流程
在实际工程中,MMU 初始化通常遵循以下步骤。每一步都涉及上述寄存器的特定位域:
- 设置 MAIR_EL1:定义 8 个内存属性区域,包括 Normal Cacheable、Device 等。
- 设置 TCR_EL1:配置 T0SZ/T1SZ、TG0/TG1、IPS 以及缓存策略。
- 写入 TTBR0_EL1 / TTBR1_EL1:将页表基地址写入对应寄存器。
- 执行 ISB:确保之前的配置指令完成。
- 设置 SCTLR_EL1:置位 M、C、I 位,使能 MMU 和缓存。
- 执行 ISB + DSB:确保 MMU 使能生效。
mrs x0, tcr_el1 和 mrs x0, mair_el1 指令读取,并与预期值比对。常见错误包括 T0SZ 设置过大导致高地址翻译失败,以及 MAIR_EL1 中 AttrIndx 索引超出已定义范围。
以下是一个典型的初始化代码片段(ARM64 汇编):
// 配置 MAIR_EL1
ldr x0, =0xBBFF4400 // Attr0=0x00, Attr1=0x00, Attr2=0x00, Attr3=0x88
// Attr4=0xBB, Attr5=0x44, Attr6=0xFF, Attr7=0x00
msr mair_el1, x0
// 配置 TCR_EL1
ldr x0, =0x80803520 // T0SZ=32, TG0=4KB, IPS=48bit
// T1SZ=32, TG1=4KB, 内外缓存写回+分配
msr tcr_el1, x0
// 写入 TTBR0_EL1(页表基地址在 x1 中)
msr ttbr0_el1, x1
// 执行 ISB 确保配置完成
isb
// 使能 MMU、数据缓存、指令缓存
mrs x0, sctlr_el1
orr x0, x0, #(1 << 0) // 置位 M 位
orr x0, x0, #(1 << 2) // 置位 C 位
orr x0, x0, #(1 << 12) // 置位 I 位
msr sctlr_el1, x0
// 执行 ISB + DSB 确保使能生效
isb
dsb sy
4.5 常见配置错误与调试方法
| 错误现象 | 可能原因 | 排查方法 |
|---|---|---|
| Translation Fault | T0SZ/T1SZ 设置错误,或页表描述符无效 | 检查 TCR_EL1 的 T0SZ/T1SZ 是否与 VA 范围匹配 |
| Permission Fault | 页表描述符中的 AP 位与 SCTLR_EL1 的 WXN 冲突 | 检查 WXN 位是否置位,以及页表 AP 字段 |
| Alignment Fault | TTBR0_EL1 未按页大小对齐 | 确保 TTBR 基地址低 12 位为 0 |
| Cache Coherency 问题 | MAIR_EL1 中 Normal 与 Device 属性混用不当 | 检查 AttrIndx 索引是否指向正确的 MAIR 槽 |
| MMU 使能后立即崩溃 | SCTLR_EL1.M 使能前未执行 ISB | 在修改 SCTLR_EL1 前后添加 ISB |