2. ARMv8-A MMU 架构基础:页表层级、转换粒度、地址空间划分(TTBR0/TTBR1)
ARMv8-A 架构的 MMU(Memory Management Unit)是驱动内存隔离与设备兼容适配的核心硬件单元。它通过多级页表、可配置的转换粒度以及双地址空间机制,为操作系统提供了灵活的虚拟地址到物理地址的映射能力。理解这些基础概念,是后续实现驱动级内存保护与设备移植的前提。
2.1 页表层级与转换粒度
ARMv8-A 支持 4KB、16KB 和 64KB 三种页面粒度,并采用最多 4 级页表(Level 0 ~ Level 3)进行地址转换。页表层级数由虚拟地址宽度和页面粒度共同决定。下表总结了常见配置下的层级关系:
| 页面粒度 | 虚拟地址宽度 | 页表层级数 | Level 0 覆盖范围 | Level 3 页大小 |
|---|---|---|---|---|
| 4KB | 48-bit | 4 级 (L0~L3) | 512GB | 4KB |
| 16KB | 48-bit | 4 级 (L0~L3) | 512GB | 16KB |
| 64KB | 48-bit | 3 级 (L1~L3) | 64TB (L1) | 64KB |
| 4KB | 39-bit | 3 级 (L1~L3) | 1GB (L1) | 4KB |
实践要点: 在驱动开发中,4KB 粒度是最常用的配置,因为它与 Linux 内核的页框管理单元高度兼容。64KB 粒度常用于需要大块连续物理内存的场景(如 GPU 驱动),但会增大页表覆盖范围,减少页表层级。
下图展示了 4 级页表(4KB 粒度,48-bit 地址)的转换流程:
关键概念: 页表层级中的每个表项(PTE)包含物理地址基址和访问权限位。当 MMU 遍历页表时,如果某一级表项标记为“块”(Block),则直接形成物理地址,不再继续下一级遍历。这种机制允许大页映射(如 2MB 或 1GB),减少 TLB 压力。
2.2 地址空间划分:TTBR0 与 TTBR1
ARMv8-A 将虚拟地址空间划分为两个独立的区域,分别由两个页表基址寄存器控制:
- TTBR0:用于低地址空间(通常为 0x0000_0000_0000_0000 起始),典型场景是用户空间。
- TTBR1:用于高地址空间(通常为 0xFFFF_0000_0000_0000 起始),典型场景是内核空间。
这种划分使得操作系统可以在上下文切换时仅切换 TTBR0(用户空间页表),而 TTBR1(内核空间页表)保持不变,从而避免内核页表的重复刷新,提升性能。
| 寄存器 | 地址范围 | 典型用途 | 切换时机 |
|---|---|---|---|
| TTBR0 | 0x0000_0000_0000_0000 ~ 0x0000_FFFF_FFFF_FFFF | 用户进程地址空间 | 进程上下文切换 |
| TTBR1 | 0xFFFF_0000_0000_0000 ~ 0xFFFF_FFFF_FFFF_FFFF | 内核地址空间 | 仅初始化或内核升级时 |
驱动开发注意: 设备驱动通常运行在内核空间(TTBR1 区域),但访问用户空间缓冲区时,需要通过
copy_from_user / copy_to_user 等内核 API 进行安全拷贝,不能直接解引用用户空间指针。这是因为用户空间地址(TTBR0 区域)在当前上下文可能尚未映射或已被换出。
下图展示了 TTBR0 与 TTBR1 在 48-bit 地址空间中的划分关系:
2.3 转换粒度与块映射
ARMv8-A 的页表支持多种映射粒度,除了基础的页面粒度外,还支持“块”(Block)映射,用于减少页表层级和 TLB 占用:
- 4KB 页面:L3 表项,粒度 4KB。
- 2MB 块:L2 表项,粒度 2MB(对应 4KB 页面配置下的 512 个连续页面)。
- 1GB 块:L1 表项,粒度 1GB(对应 4KB 页面配置下的 262144 个连续页面)。
性能优化: 在设备驱动中,如果设备需要映射大块连续的物理内存(如帧缓冲、DMA 缓冲区),应优先使用块映射(2MB 或 1GB)。这可以显著减少页表遍历次数和 TLB miss,提升内存访问性能。例如,在
ioremap 实现中,内核会尝试使用块映射来映射设备寄存器区域。
下表对比了不同粒度的适用场景:
| 粒度 | 页表级别 | 覆盖范围 | 典型应用 |
|---|---|---|---|
| 4KB | L3 | 4KB | 普通进程堆栈、小数据段 |
| 2MB | L2 | 2MB | 内核直接映射区、大块 DMA 缓冲区 |
| 1GB | L1 | 1GB | 帧缓冲、GPU 显存映射 |
2.4 页表描述符与属性控制
每个页表项(PTE)不仅包含物理地址,还包含丰富的属性位,用于控制内存访问权限、缓存策略和执行权限。以下是关键属性位:
- AP[2:1]:访问权限控制(读/写/只读,EL0/EL1 权限分离)。
- AF:访问标志位,硬件在首次访问时置位,用于页面回收算法。
- SH:可共享性属性(非共享、内部共享、外部共享),用于多核一致性。
- AttrIndx:指向 MAIR(Memory Attribute Indirection Register)的索引,定义缓存策略(如 Normal、Device、Strongly Ordered)。
- XN / PXN:禁止执行标志(XN 用于 EL1/EL2,PXN 用于 EL0),是实现 W^X 保护的关键。
安全关键: 在驱动中映射设备内存时,必须正确设置
AttrIndx 为 Device 类型(通常为 MAIR 索引 0),并设置 XN 位禁止执行。如果错误地将设备内存映射为 Normal 可缓存类型,可能导致 DMA 一致性问题或安全漏洞。例如,网卡驱动中的描述符环必须使用 Device 或 Strongly Ordered 属性。