ARMv8-A MMU 架构:页表层级、转换粒度与地址空间划分
ARMv8-A 架构的 MMU(Memory Management Unit)是整个内存映射与虚拟化机制的核心。理解其页表层级、转换粒度以及地址空间划分,是进行 MMU 配置与 DMA 缓冲区验证的理论基础。本节将深入剖析这三项关键参数,并通过图表与表格进行对比说明。
2.1 页表层级结构:4级 vs 3级
ARMv8-A 支持基于页表的虚拟地址到物理地址转换。根据配置,页表层级可以是 4 级或 3 级。层级越多,页表树的深度越大,但能支持更大的地址空间和更细粒度的内存管理。
- 4级页表(4-Level Page Table): 支持 48 位虚拟地址空间(VA),是默认且最常用的配置。层级包括:PGD(Page Global Directory)、PUD(Page Upper Directory)、PMD(Page Middle Directory)、PTE(Page Table Entry)。
- 3级页表(3-Level Page Table): 支持 39 位虚拟地址空间,层级包括:PGD、PMD、PTE。适用于地址空间需求较小的场景,可减少页表遍历开销。
关键点: 在 4 级页表配置下,如果使用 64KB 转换粒度,PUD 层级会被跳过,实际退化为 3 级页表。这是 ARM 架构的硬件优化特性。
下表对比了两种页表层级的关键差异:
| 特性 | 4级页表 | 3级页表 |
|---|---|---|
| 虚拟地址宽度 | 48 位 | 39 位 |
| 最大虚拟地址空间 | 256 TB | 512 GB |
| 页表层级 | PGD → PUD → PMD → PTE | PGD → PMD → PTE |
| 典型应用场景 | 通用 Linux 内核、大型系统 | 嵌入式系统、地址空间受限场景 |
下图展示了 4 级页表的遍历流程:
2.2 转换粒度:4K / 16K / 64K
转换粒度(Translation Granule)决定了页表中最底层页(Page)的大小。ARMv8-A 支持三种粒度:4KB、16KB 和 64KB。粒度选择直接影响页表大小、TLB 覆盖范围和内存碎片化程度。
- 4KB 粒度: 最细粒度,页表层级最多(4级),内存利用率高,但页表占用内存较大。适用于通用操作系统。
- 16KB 粒度: 折中方案,页表层级减少(3级),TLB 覆盖范围增大。适用于需要平衡性能与内存占用的场景。
- 64KB 粒度: 最粗粒度,页表层级最少(3级或2级),TLB 覆盖范围最大,但内存碎片化风险增加。适用于高性能计算或大页需求场景。
注意: 粒度选择必须在系统启动时通过 TCR(Translation Control Register)配置,且不能动态更改。DMA 缓冲区分配时,必须确保缓冲区大小与粒度对齐,否则可能导致映射失败或性能下降。
下表对比了三种粒度的关键参数:
| 参数 | 4KB 粒度 | 16KB 粒度 | 64KB 粒度 |
|---|---|---|---|
| 页大小 | 4 KB | 16 KB | 64 KB |
| 页表层级(48位VA) | 4 级(PGD/PUD/PMD/PTE) | 3 级(PGD/PMD/PTE) | 3 级(PGD/PMD/PTE) |
| 单页表项覆盖范围 | 4 KB | 16 KB | 64 KB |
| TLB 覆盖范围(相同条目数) | 小 | 中 | 大 |
| 页表内存占用 | 高 | 中 | 低 |
| 典型应用 | Linux 内核默认 | Android / 嵌入式 | 高性能计算 / 服务器 |
下图展示了不同粒度下的页表层级差异:
2.3 地址空间划分:内核空间与用户空间
ARMv8-A 支持两个独立的虚拟地址空间:用户空间(User Space) 和 内核空间(Kernel Space)。通过 TTBR0_EL1 和 TTBR1_EL1 两个页表基地址寄存器来区分。这种划分是操作系统内存保护的基础。
- 用户空间(TTBR0_EL1): 低地址区域,每个进程拥有独立的页表,进程间隔离。地址范围取决于 VA 宽度(如 48 位时为 0x0000_0000_0000_0000 ~ 0x0000_FFFF_FFFF_FFFF)。
- 内核空间(TTBR1_EL1): 高地址区域,所有进程共享同一个内核页表,用于内核代码、数据结构和设备映射。地址范围(48 位时为 0xFFFF_0000_0000_0000 ~ 0xFFFF_FFFF_FFFF_FFFF)。
实践要点: 在 DMA 缓冲区验证中,驱动程序通常将缓冲区映射到内核空间(通过
dma_alloc_coherent 或 ioremap),并可选地映射到用户空间(通过 mmap)。理解地址空间划分有助于正确配置页表属性(如缓存策略、权限位)。
下表总结了用户空间与内核空间的关键区别:
| 特性 | 用户空间 | 内核空间 |
|---|---|---|
| 页表基地址寄存器 | TTBR0_EL1 | TTBR1_EL1 |
| 地址范围(48位VA) | 0x0000_0000_0000_0000 ~ 0x0000_FFFF_FFFF_FFFF | 0xFFFF_0000_0000_0000 ~ 0xFFFF_FFFF_FFFF_FFFF |
| 页表独立性 | 每个进程独立 | 所有进程共享 |
| 访问权限 | EL0(非特权) | EL1(特权) |
| 典型内容 | 应用程序代码、堆、栈 | 内核代码、设备驱动、页表自身 |
下图展示了 ARMv8-A 的地址空间划分:
2.4 页表配置与 DMA 缓冲区验证的关联
在 DMA 缓冲区验证中,页表配置直接影响缓冲区的映射属性和访问性能。以下是几个关键关联点:
- 缓存属性: 页表项中的
AttrIndx字段控制内存类型(Normal、Device、Strongly Ordered)。DMA 缓冲区通常配置为 Normal Non-Cacheable 或 Device 类型,以避免缓存一致性问题。 - 权限位:
AP(Access Permission)和PXN/UXN(Privileged/User Execute Never)位控制访问权限。DMA 缓冲区通常需要同时具有读写权限。 - 粒度对齐: 缓冲区起始地址和大小必须与转换粒度对齐。例如,使用 4KB 粒度时,缓冲区地址必须 4KB 对齐,否则 MMU 无法正确映射。
验证技巧: 在驱动测试中,可以通过读取
/proc/self/pagemap 或使用 ioctl 查询页表项,验证 DMA 缓冲区的物理地址、缓存属性和权限位是否与预期一致。
下表总结了 DMA 缓冲区验证中常见的页表配置项:
| 配置项 | 页表字段 | 推荐值(DMA缓冲区) | 说明 |
|---|---|---|---|
| 内存类型 | AttrIndx[2:0] | Normal Non-Cacheable (0b010) | 避免 CPU 缓存与 DMA 数据不一致 |
| 访问权限 | AP[2:1] | EL0/EL1 读写 (0b00) | 允许内核和用户空间访问 |
| 执行权限 | PXN, UXN | 禁止执行 (1) | 防止缓冲区被用于代码执行 |
| 共享属性 | SH[1:0] | Inner Shareable (0b11) | 确保多核一致性 |
通过深入理解 ARMv8-A MMU 的页表层级、转换粒度和地址空间划分,开发者能够更精确地配置页表,从而为 DMA 缓冲区验证提供可靠的内存映射基础。下一节将介绍 MMU 初始化与页表构建的具体实现。