3. ARMv7-A MMU 寄存器详解:TTBR0/TTBR1、SCTLR、DACR、PRRR/NMRR
在 ARMv7-A 架构中,MMU 的行为由一组系统控制寄存器精确配置。这些寄存器决定了页表的基地址、转换粒度、内存属性、访问权限以及对齐策略。对于 QNX 实时系统而言,错误配置任何一个关键寄存器都可能导致系统崩溃、缓存一致性问题或安全漏洞。本节将逐一拆解 TTBR0、TTBR1、SCTLR、DACR、PRRR/NMRR 这五个核心寄存器的位域定义与工程配置要点。
3.1 页表基址寄存器:TTBR0 与 TTBR1
TTBR0(Translation Table Base Register 0)和 TTBR1(Translation Table Base Register 1)分别存储一级页表的基地址。ARMv7-A 通过虚拟地址的高位决定使用哪个寄存器:若虚拟地址高位为 0,则使用 TTBR0;若为 1,则使用 TTBR1。这种机制允许操作系统为内核空间(高地址)和用户空间(低地址)维护独立的页表。
| 位域 | 名称 | 描述 | 工程注意事项 |
|---|---|---|---|
| [31:14] | BASE | 一级页表基地址的高 18 位,页表必须 16KB 对齐 | QNX 中通常将页表放在非缓存、非共享的内存区域,避免页表 walk 时产生缓存一致性问题 |
| [13:7] | RGN | 页表内存区域属性(Outer 缓存策略) | 建议配置为 0b01(Outer Write-Back, Write-Allocate),提高页表遍历性能 |
| [6] | NOS | 非共享位(Not Outer Shareable) | 单核系统可置 1;多核系统需根据页表共享策略设置 |
| [5:4] | IRGN | Inner 缓存策略 | 推荐 0b11(Write-Back, Read-Allocate, Write-Allocate) |
| [3:1] | SH | 可共享属性(Shareability) | 0b00 非共享;0b11 内外共享。多核 IPC 区域必须设为共享 |
| [0] | PD0/PD1 | 页表遍历禁止位(TTBR0 使用 PD0,TTBR1 使用 PD1) | 置 1 时禁止使用该 TTBR 进行页表遍历,用于切换地址空间时临时隔离 |
3.2 系统控制寄存器:SCTLR
SCTLR(System Control Register)是 ARMv7-A 中最重要的控制寄存器之一,它控制着 MMU、缓存、对齐检查、分支预测等核心功能的使能状态。在 QNX 启动流程中,SCTLR 的配置顺序直接影响系统稳定性。
| 位域 | 名称 | 功能 | QNX 推荐值 |
|---|---|---|---|
| [0] | M | MMU 使能 | 1(使能) |
| [1] | A | 对齐检查使能 | 1(使能,捕获非对齐访问错误) |
| [2] | C | 数据缓存使能 | 1(使能) |
| [3] | W | 写缓冲使能 | 1(使能) |
| [11] | Z | 分支预测使能 | 1(使能,提升性能) |
| [12] | I | 指令缓存使能 | 1(使能) |
| [16] | EE | 端序控制(异常处理) | 0(小端) |
| [22] | U | 非对齐访问支持 | 1(允许非对齐访问,但需配合对齐检查位) |
| [29] | AFE | 访问标志使能 | 0(禁用,QNX 不使用硬件访问标志) |
| [30] | TE | Thumb 异常使能 | 0(异常处理使用 ARM 指令集) |
3.3 域访问控制寄存器:DACR
DACR(Domain Access Control Register)为 ARMv7-A 的 16 个域(Domain)分别配置访问权限。每个域对应 2 位控制字段,决定该域内页表项所映射内存的访问模式。QNX 利用域机制实现内核与用户空间的快速隔离。
| 域编号 | 位域 | 编码 | 访问模式 | QNX 典型用途 |
|---|---|---|---|---|
| 0 | [1:0] | 0b11 | Manager(管理者) | 内核关键内存区域,不检查页表权限位 |
| 1 | [3:2] | 0b01 | Client(客户端) | 用户进程内存区域,由页表项 AP 位控制权限 |
| 2 | [5:4] | 0b01 | Client | 设备寄存器映射区域 |
| 3~14 | [29:6] | 0b01 | Client | 其他内存区域 |
| 15 | [31:30] | 0b11 | Manager | 页表本身所在内存区域,避免递归权限检查 |
3.4 主区域属性寄存器:PRRR 与 NMRR
PRRR(Primary Region Remap Register)和 NMRR(Normal Memory Remap Register)共同定义了内存区域的缓存策略与共享属性。ARMv7-A 使用页表项中的 TEX[2:0]、C、B 位组合索引 PRRR/NMRR,从而决定最终的内存类型(Strongly-Ordered、Device、Normal 等)以及 Write-Back/Write-Through 策略。
| 寄存器 | 位域宽度 | 功能 | QNX 典型配置 |
|---|---|---|---|
| PRRR | 32 位,8 个 4 位字段 | 定义 TEX[2:0]/C/B 组合对应的内存类型和共享属性 | PRRR=0xEEAA4400(典型值,支持 Normal/Device/Strongly-Ordered) |
| NMRR | 32 位,8 个 4 位字段 | 定义 Normal 内存的 Inner/Outer 缓存策略 | NMRR=0x40E040E0(Inner/Outer Write-Back, Write-Allocate) |
memmap -v 命令验证实际生效的内存属性。
3.5 寄存器配置综合示例
以下代码展示了 QNX startup 汇编阶段中,上述五个寄存器的典型配置序列。该代码片段通常位于 startup.S 或 board_init.S 中,在 MMU 使能之前执行。
@ QNX ARMv7-A MMU 寄存器初始化序列 (汇编)
@ 假设页表已位于 _page_table_base
@ 1. 设置 TTBR0: 用户页表基址, Inner/Outer Write-Back, 共享
LDR r0, =_page_table_base
ORR r0, r0, #0x48 @ IRGN=0b10 (Write-Back), RGN=0b01 (Outer WB)
ORR r0, r0, #0x08 @ SH=0b01 (Inner Shareable)
MCR p15, 0, r0, c2, c0, 0 @ 写 TTBR0
@ 2. 设置 TTBR1: 内核页表基址, 属性同上
LDR r0, =_kernel_page_table
ORR r0, r0, #0x48
ORR r0, r0, #0x08
MCR p15, 0, r0, c2, c0, 1 @ 写 TTBR1
@ 3. 设置 DACR: 域0=Manager, 域1~14=Client, 域15=Manager
LDR r0, =0xC0000001 @ 域15=11b, 域0=01b, 其余默认0
MCR p15, 0, r0, c3, c0, 0 @ 写 DACR
@ 4. 设置 PRRR 和 NMRR
LDR r0, =0xEEAA4400 @ PRRR 典型值
MCR p15, 0, r0, c10, c2, 0 @ 写 PRRR
LDR r0, =0x40E040E0 @ NMRR 典型值
MCR p15, 0, r0, c10, c2, 1 @ 写 NMRR
@ 5. 设置 SCTLR: 使能 MMU, 缓存, 对齐检查, 分支预测
MRC p15, 0, r0, c1, c0, 0 @ 读 SCTLR
ORR r0, r0, #0x0001 @ M=1 (MMU 使能)
ORR r0, r0, #0x0004 @ C=1 (数据缓存)
ORR r0, r0, #0x1000 @ I=1 (指令缓存)
ORR r0, r0, #0x0002 @ A=1 (对齐检查)
ORR r0, r0, #0x0800 @ Z=1 (分支预测)
BIC r0, r0, #0x20000000 @ AFE=0 (禁用访问标志)
MCR p15, 0, r0, c1, c0, 0 @ 写 SCTLR
@ 6. 同步屏障,确保配置生效
DSB
ISB
1. TTBR0/TTBR1 的 BASE 位域是否指向有效的物理地址?
2. 页表所在内存是否配置为 Manager 域(DACR 域15)?
3. SCTLR.M 使能前,页表项是否已填充有效的下一级页表地址或块映射?
4. PRRR/NMRR 是否与页表项中的 TEX/C/B 编码一致?
3.6 寄存器配置错误案例分析
| 错误场景 | 现象 | 根因 | 解决方案 |
|---|---|---|---|
| TTBR0 未 16KB 对齐 | MMU 使能后立即触发 Undefined Instruction 异常 | 硬件忽略低位,实际页表基址错误 | 确保页表基址低 14 位为 0 |
| DACR 域0 配置为 Client | 内核访问页表时产生 Domain Fault | 页表所在域未设为 Manager,权限检查失败 | 将页表所在域设为 0b11 |
| PRRR 索引 7 配置为 Device | Normal 内存性能急剧下降 | 页表项 TEX=001/C=1/B=1 被映射为 Device 类型 | PRRR 索引 7 应配置为 Normal Write-Back |
| SCTLR.A=1 但 U=0 | 非对齐访问触发 Data Abort | 对齐检查使能但非对齐支持未使能 |