arm64 linux内核虚拟内存布局

linux在arm64中的内存布局

在AArch64架构的Linux内核中,内存管理的核心机制之一是虚拟地址空间的划分与页表转换。本文将基于内核文档Documentation/arch/arm64/memory.rst​,深入解析4KB页和64KB页两种模式下的内存布局差异,以及它们在ELF启动场景中的实际应用。

一、内存布局的核心设计原则

AArch64架构通过页大小转换表级别的组合,实现灵活的虚拟地址空间配置。核心设计目标包括:

  • 用户空间与内核空间隔离通过虚拟地址最高位TTBR0/1(63位)区分,用户空间最高位为0​​,内核空间为1​​
  • 转换效率与地址空间平衡:小页(4KB)提供更细粒度的内存管理,大页(64KB)减少页表层级以提升转换效率。
  • 兼容性与扩展性:支持3级/4级转换表(4KB页)和2级/3级转换表(64KB页),适配不同硬件平台。

二、4KB页模式:细腻控制与超大地址空间

1. 地址空间划分

(1)3级转换表(39位虚拟地址,512GB)

  • 用户空间0x0000000000000000 ~ 0x0000007fffffffff​(512GB)
  • 内核空间0xffffff8000000000 ~ 0xffffffffffffffff​(512GB)

(2)4级转换表(48位虚拟地址,256TB)

  • 用户空间0x0000000000000000 ~ 0x0000ffffffffffff​(256TB)
  • 内核空间0xffff000000000000 ~ 0xffffffffffffffff​(256TB)

2. 转换表结构

  1. 3级表
1
2
3
4
+--------+--------+--------+--------+--------+--------+--------+--------+
|63-56 |55-48 |47-40 |39-32 |31-24 |23-16 |15-8 |7-0 |
+--------+--------+--------+--------+--------+--------+--------+--------+
| 保留 | L0索引 | L1索引 | L2索引 | 页内偏移(12位) |
  • L0 索引(55-48 位,8 位) :指向页全局目录(PGD,Page Global Directory)。
  • L1 索引(47-40 位,8 位) :指向页上级目录(PUD,Page Upper Directory)。
  • L2 索引(39-32 位,8 位) :指向页中间目录(PMD,Page Middle Directory)。
  • 页内偏移(31-0 位,32 位中实际使用 12 位) :定位 4KB 页内的具体地址(2^12=4KB​)。
  1. 4级表
1
2
3
4
5
6
7
8
9
10
11
+--------+--------+--------+--------+--------+--------+--------+--------+
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
+--------+--------+--------+--------+--------+--------+--------+--------+
| | | | | |
| | | | | v
| | | | | [11:0] 页内偏移
| | | | +-> [20:12] L3 索引
| | | +-----------> [29:21] L2 索引
| | +---------------------> [38:30] L1 索引
| +-------------------------------> [47:39] L0 索引
+-------------------------------------------------> [63] TTBR0/1 |
  • L0-L3索引:逐级定位页表项,最终通过12位偏移访问4KB页内数据。

  • 适用场景:适合需要超大地址空间的服务器场景(如数据库、大数据处理),或对内存碎片化敏感的应用。

3. ELF启动适配

  • 页大小标识:内核映像头部flags​字段的位1-2​标识页大小(1​表示4KB)。
  • 转换表初始化:引导程序需根据flags​配置TTBRx寄存器(TTBR1指向内核页表,TTBR0指向用户页表)。

三、64KB页模式:高效转换与简化层级

1. 地址空间划分

(1)2级转换表(42位虚拟地址,4TB)

  • 用户空间0x0000000000000000 ~ 0x000003ffffffffff​(4TB)
  • 内核空间0xfffffc0000000000 ~ 0xffffffffffffffff​(4TB)

(2)3级转换表(48位虚拟地址,256TB)

  • 地址范围与4KB页的4级表一致,但通过更少的转换层级实现。

2. 转换表结构

  1. 二级表

    1
    2
    3
    4
    +--------+--------+--------+--------+--------+--------+--------+--------+
    |63-56 |55-48 |47-40 |39-32 |31-24 |23-16 |15-8 |7-0 |
    +--------+--------+--------+--------+--------+--------+--------+--------+
    | 保留 | L1索引 | L2索引 | 页内偏移(16位) |
  • L1 索引(55-48 位,8 位) :指向页上级目录(PUD,仅 2 级表时兼任 PGD 角色)。

  • L2 索引(47-32 位,16 位) :直接指向页表项(PTE,Page Table Entry),包含物理页基址。

  • 页内偏移(31-0 位,32 位中实际使用 16 位) :定位 64KB 页内的具体地址(2^16=64KB​)。

  1. 三级表
1
2
3
4
5
6
7
8
9
10
+--------+--------+--------+--------+--------+--------+--------+--------+
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
+--------+--------+--------+--------+--------+--------+--------+--------+
| | | | |
| | | | v
| | | | [15:0] 页内偏移
| | | +----------> [28:16] L3 索引
| | +--------------------------> [41:29] L2 索引
| +-------------------------------> [47:42] L1 索引
+-------------------------------------------------> [63] TTBR0/1
  • L1-L2索引:仅需两级转换即可定位64KB页(16位页内偏移),减少页表访问次数。
  • 适用场景:嵌入式设备或对内存访问延迟敏感的场景(如实时系统),通过大页提升TLB命中率。

3. ELF启动适配

  • 页大小标识flags​字段位1-2​设为3​(64KB)。
  • 性能优化:因层级少,EL2(Hypervisor)映射内核页时效率更高(如KVM的固定偏移映射0x0000004000000000~0x0000007fffffffff​)。

四、核心差异对比

特性 4KB页(3级/4级表) 64KB页(2级/3级表)
虚拟地址空间 512GB(3级)/256TB(4级) 4TB(2级)/256TB(3级)
转换表层级 3/4级,复杂度高 2/3级,层级少,访问快
内存粒度 细腻(适合小内存分配) 粗犷(适合大页分配,减少页表数量)
TLB命中率 低(小页导致TLB条目多) 高(大页减少TLB缺失)
典型场景 服务器(需要超大地址空间) 嵌入式/实时系统(追求转换效率)
ELF启动配置 flags​页大小位设为1​(4KB) flags​页大小位设为3​(64KB)

五、KVM虚拟化场景的特殊映射

当使用KVM时,Hypervisor(EL2)通过固定偏移映射内核页,强制将内核虚拟地址的高24位清零,形成专属区域:

  • 映射范围0x0000004000000000 ~ 0x0000007fffffffff​(256GB)
  • 目的:实现内核对象在Hypervisor层的直接访问,避免频繁模式切换,提升虚拟化性能。

六、总结:如何选择合适的页模式?

  1. 需求驱动

    • 若需要256TB超大地址空间(如云计算、大规模数据处理),选择4KB页+4级表或64KB页+3级表。
    • 若追求低延迟、高TLB命中率(如嵌入式设备、实时应用),优先64KB页+2级表。
  2. ELF启动配置
    通过内核映像头部flags​字段显式声明页大小,确保引导程序正确初始化转换表(如text_offset​计算、TTBR寄存器配置)。

  3. 兼容性考量
    旧版内核(如v4.2前)可能对页大小有默认假设,需结合Documentation/arm64/booting.rst​验证配置。

理解AArch64内存布局的核心是掌握页大小、转换表层级与地址空间的关系,这不仅是内核启动的关键环节,更是优化系统性能、适配不同硬件平台的基础。通过合理选择页模式,可在地址空间、转换效率、内存利用率之间找到最佳平衡。

七、实例

  1. 内核配置内存页模式
1
2
3
4
5
6
7
// 4KB页+3级表(内核配置)
CONFIG_ARM64_4K_PAGES=y
CONFIG_ARM64_VA_BITS_39=y

// 64KB页+3级表(内核配置)
CONFIG_ARM64_64K_PAGES=y
CONFIG_ARM64_VA_BITS_52=y
  1. 查看当前内核页模式

    1
    2
    3
    4
    5
    6
    7
    # 4KB页
    $ cat /proc/meminfo | grep "PageSize"
    PageSize: 4096 kB

    # 64KB页
    $ cat /proc/meminfo | grep "PageSize"
    PageSize: 65536 kB