ARM64 Linux内核MMU页表配置与TLB管理 - 第1节
1.1 AArch64 执行状态
ARMv8 架构引入了两种执行状态:AArch32 和 AArch64。本课程聚焦于 AArch64 状态,它是 64 位 ARM 架构的核心执行环境,也是 Linux 内核运行的基础。
1.1.1 AArch64 关键特性
- 64 位虚拟地址空间:支持 48 位(经典)或 52 位(扩展)虚拟地址,最大可寻址 4PB(48 位)或 16EB(52 位)。
- 31 个通用寄存器:X0-X30,每个均为 64 位宽。X30 用作链接寄存器(LR)。
- 栈指针寄存器:SP_EL0 和 SP_ELx(x=1,2,3),每个异常等级拥有独立的栈指针。
- 程序计数器:PC,64 位宽,不可直接写入。
- 异常链接寄存器:ELR_ELx,用于保存异常返回地址。
- 保存的状态寄存器:SPSR_ELx,保存异常发生时的处理器状态。
关键区别:与 AArch32 相比,AArch64 取消了 CPSR 的直接访问模式,改用 SPSR_ELx 保存异常上下文;通用寄存器数量从 15 个(R0-R14)扩展到 31 个(X0-X30),显著减少了栈帧保存/恢复的开销。
1.1.2 寄存器模型对比
| 特性 | AArch32 | AArch64 |
|---|---|---|
| 通用寄存器 | 15 个(R0-R14) | 31 个(X0-X30) |
| PC 可写性 | 可直接写入(如 MOV PC, LR) | 不可直接写入 |
| 栈指针 | R13(SP) | SP_EL0 / SP_ELx |
| 异常返回 | SUBS PC, LR | ERET |
| 虚拟地址宽度 | 32 位 | 48/52 位 |
1.2 异常等级(Exception Levels)
ARMv8-A 架构定义了四个异常等级(EL0-EL3),用于实现不同特权级别的软件隔离。这是操作系统内核安全隔离的硬件基础。
1.2.1 异常等级定义
| 异常等级 | 名称 | 运行软件 | 特权级别 |
|---|---|---|---|
| EL0 | 用户态 | 应用程序 | 最低 |
| EL1 | 内核态 | 操作系统内核 | 中等 |
| EL2 | 虚拟机监控器 | Hypervisor | 高 |
| EL3 | 安全监控器 | Secure Monitor | 最高 |
1.2.2 异常等级切换规则
- 异常捕获:低等级向高等级切换(如 EL0 → EL1),通过同步异常(SVC、HVC、SMC)或异步异常(IRQ、FIQ、SError)触发。
- 异常返回:高等级向低等级切换(如 EL1 → EL0),通过
ERET指令实现。 - 等级提升:只能逐级或跨级向更高等级切换(如 EL0 → EL1 或 EL0 → EL2)。
- 等级降低:只能向更低等级切换,不能直接跳转到同级或更高级。
重要约束:EL0 无法直接访问页表基地址寄存器 TTBR0_EL1/TTBR1_EL1,也无法执行 DSB/ISB 等屏障指令。所有页表操作必须由 EL1 及以上等级完成。
1.3 内存模型基础
ARMv8-A 内存模型定义了处理器如何访问内存、缓存一致性、内存排序以及设备内存的访问规则。理解内存模型是正确配置 MMU 和页表的前提。
1.3.1 内存类型
| 内存类型 | 属性 | 典型用途 | 缓存策略 |
|---|---|---|---|
| Normal | 可缓存、可合并、可重排 | DRAM、内核代码、用户数据 | Write-Back / Write-Through |
| Device | 不可缓存、严格排序 | MMIO 寄存器、外设内存 | Non-Cacheable |
| Strongly Ordered | 严格排序、完全同步 | 中断控制器、系统控制寄存器 | Non-Cacheable |
1.3.2 内存属性与页表描述符
在页表描述符中,通过 AttrIndx 字段(位[4:2])索引 MAIR_EL1 寄存器中的属性编码。MAIR_EL1 包含 8 个属性字段,每个字段 8 位,定义内存类型和缓存策略。
// MAIR_EL1 寄存器格式(8 个属性字段,每个 8 位)
// 位 [63:56] Attr7 | [55:48] Attr6 | [47:40] Attr5 | [39:32] Attr4
// 位 [31:24] Attr3 | [23:16] Attr2 | [15:8] Attr1 | [7:0] Attr0
// Linux 内核典型配置
#define MAIR_ATTR_NORMAL_WB 0xFF // Normal Write-Back 可缓存
#define MAIR_ATTR_NORMAL_WT 0xBB // Normal Write-Through 可缓存
#define MAIR_ATTR_DEVICE_nGnRnE 0x00 // Device 非缓存非聚集非重排
#define MAIR_ATTR_NORMAL_NC 0x44 // Normal Non-Cacheable
1.3.3 内存排序模型
ARMv8 采用弱排序(Weakly Ordered)内存模型,允许处理器和编译器对内存访问进行重排,以提高性能。但对外设访问和多核同步场景,必须使用内存屏障指令保证顺序。
| 屏障指令 | 作用 | 使用场景 |
|---|---|---|
| DMB | 数据内存屏障 | 保证屏障前后的数据访问顺序 |
| DSB | 数据同步屏障 | 等待所有内存访问完成后再执行后续指令 |
| ISB | 指令同步屏障 | 刷新流水线,保证后续指令从缓存/内存重新读取 |
页表切换关键点:修改 TTBR0_EL1/TTBR1_EL1 后,必须依次执行 DSB(确保页表写入完成)和 ISB(刷新流水线),否则处理器可能使用过期的 TLB 条目。
1.4 本章小结
- AArch64 执行状态:提供 31 个 64 位通用寄存器、独立的栈指针和异常链接寄存器,是 Linux 内核运行的基础硬件环境。
- 异常等级(EL0-EL3):实现从用户态到安全监控器的四级特权隔离,页表配置和 TLB 管理主要在 EL1(内核态)完成。
- 内存模型:区分 Normal/Device/Strongly Ordered 三种内存类型,通过 MAIR_EL1 和页表描述符 AttrIndx 字段协同配置内存属性。
- 内存屏障:DMB/DSB/ISB 是保证页表切换正确性的关键指令,任何 TTBR 寄存器的修改都必须配合屏障指令使用。