news 2026/9/2 2:16:25

ARM64地址空间详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ARM64地址空间详解

ARM64地址空间详解:VA_BITS vs PA_BITS

你有没有想过:为什么32GB的物理内存,设备MMIO地址却可能在64GB甚至更高?

📚 概述

本文解决什么问题?

  • ❓ 为什么有32GB物理内存,但设备MMIO地址可能在64GB甚至更高?
  • ❓ 虚拟地址位宽(VA_BITS)和物理地址位宽(PA_BITS)有什么区别?
  • ❓ 它们如何影响系统的地址空间布局?

📍 适合读者

  • 🔧 嵌入式系统工程师
  • 🐧 Linux内核开发初学者
  • 💻 需要理解ARM64内存布局的开发者

📋 前置知识

  • ✓ 理解虚拟内存基本概念
  • ✓ 了解MMU的作用
  • ✓ 熟悉Linux基本命令

🎯 核心概念

概念1:物理地址空间 ≠ 物理内存大小

这是最容易混淆的地方!让我们用生活类比理解:

🏙️城市类比

  • 物理地址空间= 一个城市所有的门牌号范围(0号 ~ 10000号)
  • 物理内存= 实际建了房子的门牌号(只有100个地址有房子)

剩下的门牌号被分配给:

  • 🏞️ 公园(设备MMIO)
  • 🅿️ 停车场(保留区域)
  • 🌾 空地(未使用)
关键理解
✓ CPU的地址总线有N条线,可以访问 2^N 个地址 ✓ 但不是所有地址都对应DRAM(内存) ✓ 很多地址对应设备寄存器(MMIO)、ROM、保留区域

概念2:ARM64的地址空间组成

物理地址空间(48位地址总线示例)
┌─────────────────────────────────────────────────┐ │ 总容量:2^48 = 256TB 可寻址空间 │ ├─────────────────────────────────────────────────┤ │ │ │ 0x0000_0000_0000 ~ 0x0000_FFFF_FFFF │ │ └─ 低地址外设MMIO(串口、I2C、SPI等) │ │ │ │ 0x0001_0000_0000 ~ 0x0007_FFFF_FFFF │ │ └─ SoC集成外设(GPU寄存器、ISP、DLA等) │ │ │ │ 0x0008_0000_0000 ~ 0x000F_FFFF_FFFF │ │ └─ DRAM物理内存(你的32GB在这里!) │ │ │ │ 0x0010_0000_0000 ~ 0x001F_FFFF_FFFF │ │ └─ PCIe设备MMIO(如果有扩展卡) │ │ │ │ 0x0020_0000_0000 ~ 0x002F_FFFF_FFFF │ │ └─ GPU Carveout / Framebuffer │ │ │ │ ...(其他设备和保留区域) │ │ │ │ 0xFFFF_FFFF_FFFF(256TB顶部) │ └─────────────────────────────────────────────────┘

💾 VA_BITS:虚拟地址位宽

定义

VA_BITS= 虚拟地址有效位数

控制范围
  • 📊 虚拟地址空间大小(用户空间 + 内核空间)
  • 🌳 页表级数(4级/3级/2级)
  • ⚡ 系统性能(TLB miss频率)

ARM64支持的VA_BITS配置

VA_BITS总虚拟空间用户空间内核空间页表级数适用场景
48512 TB256 TB256 TB4级服务器
47256 TB128 TB128 TB4级高端服务器
428 TB4 TB4 TB3级高端嵌入式
391 TB512 GB512 GB3级⭐ 推荐(嵌入式)
36128 GB64 GB64 GB3级受限嵌入式

虚拟地址空间布局

以VA_BITS=48为例:完整的512TB虚拟地址空间
┌────────────────────────────────────────────────┐ │ 0xFFFF_FFFF_FFFF_FFFF │ │ ↑ │ │ 📌 内核空间 (256TB) │ │ • 内核代码和数据 │ │ • vmalloc区域 │ │ • 直接映射区域(所有物理内存) │ │ • 所有进程共享 │ │ ↓ │ │ 0xFFFF_0000_0000_0000 │ ├────────────────────────────────────────────────┤ │ 🚫 中间空洞(Canonical Hole) │ │ 不可访问,触发异常 │ ├────────────────────────────────────────────────┤ │ 0x0000_FFFF_FFFF_FFFF │ │ ↑ │ │ 👤 用户空间 (256TB) │ │ • 代码段(.text) │ │ • 数据段(.data/.bss) │ │ • 堆(heap) │ │ • 共享库 │ │ • 栈(stack) │ │ • 每个进程独立 │ │ ↓ │ │ 0x0000_0000_0000_0000 │ └────────────────────────────────────────────────┘

VA_BITS的三大影响

影响1️⃣:页表级数
4KB页表时的页表级数与VA_BITS的关系: VA_BITS=48: 4级页表 • Level 0 (PGD): VA[47:39], 覆盖512GB • Level 1 (PUD): VA[38:30], 覆盖1GB • Level 2 (PMD): VA[29:21], 覆盖2MB • Level 3 (PTE): VA[20:12], 覆盖4KB VA_BITS=39: 3级页表(省略Level 0) • Level 1 (PGD): VA[38:30], 覆盖1GB • Level 2 (PMD): VA[29:21], 覆盖2MB • Level 3 (PTE): VA[20:12], 覆盖4KB
影响2️⃣:TLB性能

性能差异明显

  • 4级页表:TLB miss时需要4次内存访问(约150ns)
  • 3级页表:TLB miss时需要3次内存访问(约110ns)
  • 性能提升:约25%🚀
影响3️⃣:内存开销
每级页表占用4KB内存(512项 × 8字节) 典型进程的页表开销: VA_BITS=48 (4级): ~1.5MB VA_BITS=39 (3级): ~1.2MB ─────── 节省:约 20% 💰

🧠 PA_BITS:物理地址位宽

定义

PA_BITS= 物理地址有效位数

控制范围
  • 📍 最大可寻址的物理地址范围
  • 📄 页表条目(PTE)中物理地址字段的宽度

ARM64支持的PA_BITS配置

PA_BITS最大物理地址空间典型应用场景
524 PB未来扩展
48256 TB服务器
4416 TB高端嵌入式
424 TB中端嵌入式
401 TB低端嵌入式
39512 GB简单场景
3664 GB最小配置

PA_BITS如何限制物理地址?

🔑 关键:页表条目(PTE)的格式
PTE是64位的,其中物理地址字段受PA_BITS限制: PTE结构(64位): ┌──┬──┬─────┬─────┬──────────────────────┬──────┬─┬─┐ │63│62│58:55│50:48│ PA_BITS-1:12 │11:2 │1│0│ ├──┼──┼─────┼─────┼──────────────────────┼──────┼─┼─┤ │UXN│PXN│SW │Res │ 物理页帧号(PFN) │Attrs │T│V│ └──┴──┴─────┴─────┴──────────────────────┴──────┴─┴─┘ ^^^^^^^^^^^^^^^^^^^^ 这部分受PA_BITS限制! PA_BITS=48: PTE[47:12] = 36位物理页帧号 PA_BITS=39: PTE[38:12] = 27位物理页帧号(高位被忽略)

实际案例:为什么设备地址超过物理内存大小?

📱 案例1:NVIDIA Orin-X
物理内存:32GB 物理地址布局(从/proc/iomem读取): 00110000-0c6a057f : 外设MMIO(串口、I2C、GPIO等) 0e000000-24700000 : SoC集成外设(GPU寄存器、DLA等) 40070000-40071fff : SYSRAM共享内存 80000000-19fffffff: System RAM (6.5GB) 1a0000000-1ffffffff: 保留区域 200000000-81b7f9fff: System RAM (26GB) ← 注意这里 81b7fa000-81b7fffff: 保留 最高物理地址:0x81b7f9fff ≈ 34.9GB

💡分析

  • 物理内存只有32GB(0x8_0000_0000字节)
  • 但最高物理地址到了34.9GB
  • 中间有外设MMIO、保留区域等填充
🖥️ 案例2:典型服务器(假设)
如果有PCIe扩展设备: 物理地址布局: 0x0000_0000_0000 ~ 0x0010_0000_0000 : 64GB DRAM 0x0010_0000_0000 ~ 0x0020_0000_0000 : PCIe设备1 MMIO (64GB空间) 0x0020_0000_0000 ~ 0x0030_0000_0000 : PCIe设备2 MMIO (64GB空间) 0x0030_0000_0000 ~ 0x0038_0000_0000 : GPU Framebuffer (32GB空间)
✅ PA_BITS的影响对比

如果PA_BITS=39(最大512GB):

✅ 可以访问到 0x80_0000_0000(512GB) ✅ 所有设备都在范围内

如果PA_BITS=36(最大64GB):

❌ 只能访问到 0x10_0000_0000(64GB) ❌ PCIe设备和GPU无法访问!

🔄 VA_BITS vs PA_BITS:详细对比

它们各管什么?

特性VA_BITSPA_BITS
控制范围虚拟地址空间大小物理地址寻址能力
影响页表页表级数(高度)PTE物理地址字段宽度
影响TLBTLB miss遍历次数无直接影响
影响用户程序进程最大虚拟内存透明(通过页表映射)
影响设备透明限制设备MMIO最大地址
运行时修改不可(需重启)不可(需重启)

可以独立配置吗?

完全可以!它们互不冲突。

常见配置组合

配置1:VA_BITS=48, PA_BITS=48

用途:服务器、大内存系统 特点:虚拟空间大,支持高地址设备 开销:4级页表

配置2:VA_BITS=39, PA_BITS=48推荐!

用途:嵌入式、Orin-X等 特点:虚拟空间够用,支持高地址设备 开销:3级页表,性能更好 适合:虚拟空间需求<512GB,但设备可能在高地址

配置3:VA_BITS=39, PA_BITS=39

用途:简单嵌入式系统 特点:虚拟和物理都限制在512GB 开销:最小 要求:确认所有设备地址<512GB

配置4:VA_BITS=48, PA_BITS=39(少见)

用途:大虚拟空间但物理有限 特点:进程可用大虚拟空间,但物理地址受限 问题:设备受限,一般不推荐

混合配置深度解析

场景:VA_BITS=39, PA_BITS=48
虚拟地址翻译过程: 虚拟地址: 0x0000_007F_1234_5678 (39位有效) ┌────┬────┬────┬────┐ │ L1 │ L2 │ L3 │off │ │255 │145 │52 │678 │ └─┬──┴─┬──┴─┬──┴────┘ │ │ │ PGD───→PUD PMD PTE (L1) (L2) (L3) 【页表遍历步骤】 1️⃣ TTBR0_EL1 → PGD表(Level 1起始) 2️⃣ VA[38:30] → PGD[255] → PMD表地址 3️⃣ VA[29:21] → PMD[145] → PTE表地址 4️⃣ VA[20:12] → PTE[52] → 读取PTE
PTE内容解析
PTE内容(64位): ┌──┬──┬─────┬──────────────────────────┬──────────┐ │ │ │ │ 物理地址[47:12] (36位) │ │ │ │ │ │ 0x0002_ABCD_EF00_0 │ 0x783 │ └──┴──┴─────┴──────────────────────────┴──────────┘ ↑ PA_BITS=48允许存储完整的48位物理地址
最终物理地址计算
PA = (0x0002_ABCD_EF00_0 << 12) | 0x678 = 0x0002_ABCD_EF00_0678 ← 这是一个48位物理地址!

📌关键结论

  • 虚拟空间只有512GB(VA_BITS=39)
  • 但可以映射到256TB范围内的任意物理地址(PA_BITS=48)
  • 适合:进程虚拟内存不大,但设备MMIO在高地址

🧮 地址位宽计算

地址空间大小计算

快速换算技巧
每增加1位,容量翻倍: 基准值: 2^10 = 1024 = 1K 2^20 = 1024K = 1M 2^30 = 1024M = 1G 2^40 = 1024G = 1T 推导: 2^39 = 2^40 / 2 = 1TB / 2 = 512GB 2^42 = 2^40 * 4 = 1TB * 4 = 4TB 2^48 = 2^40 * 256 = 1TB * 256 = 256TB
常用地址空间大小表
位宽计算结果实际大小
482^48281,474,976,710,656256 TB
422^424,398,046,511,1044 TB
402^401,099,511,627,7761 TB
392^39549,755,813,888512 GB
362^3668,719,476,73664 GB
322^324,294,967,2964 GB

🔍 实际案例分析

NVIDIA Orin-X平台深度分析

硬件配置
- SoC: NVIDIA Tegra234 (Orin) - CPU: ARM Cortex-A78AE (12核) - 物理内存: 32GB LPDDR5
当前内核配置(查看方法)
# 查看VA_BITSzcat /proc/config.gz|grepCONFIG_ARM64_VA_BITS# 输出: CONFIG_ARM64_VA_BITS=48# 查看PA_BITSzcat /proc/config.gz|grepCONFIG_ARM64_PA_BITS# 输出: CONFIG_ARM64_PA_BITS=48# 查看页大小zcat /proc/config.gz|grepCONFIG_ARM64_4K_PAGES# 输出: CONFIG_ARM64_4K_PAGES=y
实际物理地址布局
$sudocat/proc/iomem|awk-F'-''{print $2}'|sort-u|tail-10

关键地址:

81b7f9fff : System RAM结束地址 转换为GB: 0x81b7f9fff = 0x8_1b7f_9fff ≈ 34.9 GB
🎯 优化建议

当前配置:

CONFIG_ARM64_VA_BITS=48 // 4级页表 CONFIG_ARM64_PA_BITS=48 // 支持256TB

推荐配置:

CONFIG_ARM64_VA_BITS=39 // 3级页表,减少25% TLB miss ⚡ CONFIG_ARM64_PA_BITS=48 // 保持48位(保险)

激进配置(需验证):

CONFIG_ARM64_VA_BITS=39 // 3级页表 CONFIG_ARM64_PA_BITS=39 // 确保所有设备<512GB

预期性能提升:

📊 TLB密集型任务:5-10% 💾 页表内存节省:10-15%

📋 核心要点总结

关键概念速览

概念简单理解
物理地址空间CPU地址总线能"看到"的全部地址范围(包括内存+设备)
物理内存大小实际DRAM芯片的容量(只是地址空间的一部分)
VA_BITS虚拟地址有多少位有效,决定虚拟空间大小和页表级数
PA_BITS物理地址有多少位有效,决定能访问的最高物理地址

快速参考表

VA_BITS配置表(4KB页)
VA_BITS总虚拟空间页表级数每级覆盖适用场景
48512TB4级512GB→1GB→2MB→4KB服务器
391TB3级1GB→2MB→4KB嵌入式(推荐)
36128GB3级1GB→2MB→4KB受限嵌入式
PA_BITS配置表
PA_BITS最大物理地址适用条件
48256TB有PCIe扩展/不确定设备地址
424TB中大型嵌入式系统
39512GB确认所有设备<512GB
3664GB简单系统,设备都在低地址

⚠️ 常见误区

❌ 误区1:物理内存32GB,PA_BITS=32就够了

❌ 错误想法:内存就32GB,32位地址搞定 ✅ 正确理解: • 设备MMIO可能在更高地址 • 需要检查/proc/iomem找出最高地址 • 实际Orin-X最高地址到了34.9GB!

❌ 误区2:VA_BITS越大越好

❌ 错误想法:虚拟地址位数多,功能更强 ✅ 正确理解: • VA_BITS越大,页表级数越多 • TLB miss时遍历次数越多,性能越差 • VA_BITS=39通常比48性能提升25%

❌ 误区3:VA_BITS和PA_BITS必须相等

❌ 错误想法:这两个值必须保持一致 ✅ 正确理解: • 它们完全独立 • 可以任意组合(VA_BITS=39, PA_BITS=48) • 这样配置往往性能最优

❌ 误区4:修改配置不需要重启

❌ 错误想法:改改参数就能生效 ✅ 正确理解: • 必须重新编译内核 • 必须重启系统 • 无法热修改

📚 延伸阅读与验证命令

实用命令速查

# 【配置检查】zcat /proc/config.gz|grep-E"ARM64_VA_BITS|ARM64_PA_BITS|ARM64.*PAGE"# 【物理地址布局】sudocat/proc/iomem# 【最高物理地址】sudocat/proc/iomem|awk-F'-''{print $2}'|sort-u|tail-1# 【进程虚拟内存布局】cat/proc/self/maps# 【虚拟内存统计】cat/proc/meminfo|grep-E"VmallocTotal|MemTotal"# 【页大小】getconf PAGE_SIZE

相关文档(后续)

  • 📖 文档2:ARM64多级页表结构详解
  • 📖 文档3:ARM64 MMU硬件工作原理
  • 📖 文档5:页表配置优化实践指南

ARM官方文档

  • 📄 ARM Architecture Reference Manual ARMv8 (DDI 0487)
  • 📄 ARM Cortex-A78 Technical Reference Manual
  • 📄 Linux kernel source:arch/arm64/Kconfig

🎓 决策树:如何选择配置?

❓ 如何选择VA_BITS? ├─ 进程需要>512GB虚拟内存? │ ├─ 是 → VA_BITS=48 │ └─ 否 → VA_BITS=39 (推荐,性能更好) │ ❓ 如何选择PA_BITS? ├─ 检查 /proc/iomem 最高地址 │ ├─ < 64GB → PA_BITS=36 │ ├─ < 512GB → PA_BITS=39 │ └─ > 512GB → PA_BITS=48 │ ❓ 页大小选择? ├─ 有闭源驱动(NVIDIA等)? │ ├─ 是 → 4KB(安全) │ └─ 否 → 可尝试64KB(性能更好)

📌 最终总结

一句话理解

物理地址空间= 总能访问的地址范围
物理内存= 其中有数据的部分
VA_BITS= 虚拟地址空间有多大
PA_BITS= 物理地址能有多大


适用平台:ARM64 (ARMv8-A)
内核版本:Linux 5.15+

💬有问题?欢迎在评论区讨论!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 17:28:01

Spring如何处理线程并发问题

Spring 作为 Java 企业级开发框架&#xff0c;本身并不直接提供「线程并发问题」的解决方案&#xff0c;但它整合了 Java 并发编程的核心能力&#xff0c;并通过自身的特性&#xff08;如作用域、事务、AOP 等&#xff09;帮助开发者规避或解决并发场景下的线程安全问题。下面我…

作者头像 李华
网站建设 2026/7/14 17:28:01

WSL 实用技巧:设置默认 Root 用户与系统快照备份

在 Windows 上使用 WSL (Windows Subsystem for Linux) 进行开发时&#xff0c;我们经常需要以 root 权限执行操作&#xff0c;也常常担心把环境改乱了无法恢复。本文将分享两个非常实用的 WSL 技巧&#xff1a;如何将默认登录用户设置为 root 以及 如何像虚拟机一样给 WSL 系统…

作者头像 李华
网站建设 2026/7/14 17:28:00

C++静态多态技术

1、非修改序列算法这些算法不会改变它们所操作的容器中的元素。1.1 find 和 find_iffind(begin, end, value)&#xff1a;查找第一个等于 value 的元素&#xff0c;返回迭代器&#xff08;未找到返回 end&#xff09;。find_if(begin, end, predicate)&#xff1a;查找第一个满…

作者头像 李华
网站建设 2026/7/14 17:27:59

用过才敢说 9个降AI率网站测评:专科生降AI率全攻略

在当前高校论文评审中&#xff0c;AI生成内容的痕迹越来越容易被检测出来&#xff0c;尤其是对于专科生来说&#xff0c;如何有效降低AIGC率、去除AI痕迹&#xff0c;同时又不破坏文章的逻辑性和语义通顺&#xff0c;成为了一个亟需解决的问题。AI降重工具的出现&#xff0c;正…

作者头像 李华
网站建设 2026/7/14 17:27:59

AI写教材工具大揭秘,低查重秘诀让你的教材脱颖而出!

教材格式复杂繁琐一直是编写者们共同面临的问题。标题应该使用什么字号、选择哪一级层级呢&#xff1f;参考文献是依据GB/T7714标准&#xff0c;还是要遵循某些出版机构的特定要求&#xff1f;关于习题的排版&#xff0c;单栏或双栏的选择也是让人困惑。面对这些不同的要求&…

作者头像 李华