1. ARMv9 架构概览:从 v8 到 v9 的演进、核心特性与 AArch64 执行状态详解

各位好,我是老周。今天咱们正式开讲 ARMv9。说实话,我第一次拿到 ARMv9 的架构手册时,第一反应是——这不就是 v8 的加强版吗?但深入看下去才发现,事情没那么简单。

ARMv9 是 ARM 公司在 2021 年发布的重大架构版本。它并不是推倒重来,而是在 v8 的基础上做了三个方向的深度进化:安全、可扩展、高性能计算。你想想看,从手机到服务器,从嵌入式到超算,ARM 想用 v9 一统天下,没点真功夫可不行。

核心观点:ARMv9 不是 v8 的替代品,而是 v8 的进化版。v8 的代码可以在 v9 上直接跑,但 v9 新增的特性,v8 永远用不了。

1.1 从 v8 到 v9:到底改了啥?

我习惯用一张表来对比这两个架构。这样最直观。

特性维度 ARMv8 ARMv9
指令集 A64 + A32/T32 A64 为主,A32 逐步淘汰
地址空间 48 位虚拟地址 52 位虚拟地址(可选)
安全架构 TrustZone CCA(机密计算架构)+ TrustZone
向量扩展 NEON(128 位) SVE2(可伸缩向量,128-2048 位)
调试与跟踪 CoreSight CoreSight + 增强分支记录
虚拟化 VHE(虚拟化主机扩展) 增强 VHE + 嵌套虚拟化

看到没?v9 最大的变化在三个地方:SVE2、CCA、52 位地址。咱们一个一个说。

1.2 ARMv9 三大核心特性

1.2.1 SVE2:可伸缩向量扩展第二代

SVE2 是 v9 最亮眼的特性之一。说白了,它让 CPU 能一次处理更多数据。我在做 AI 推理加速时,SVE2 的向量长度灵活性帮了大忙。

  • 向量长度可变:128 位到 2048 位,步长 128 位。同一个二进制,在不同核心上自动适配。
  • 谓词执行:每条向量指令都可以带一个谓词掩码,实现条件化运算。这比传统分支预测高效得多。
  • 聚集/分散加载:支持非连续内存访问,处理稀疏数据时性能提升明显。

避坑指南:我曾经在一个项目中,直接用 NEON 指令优化图像处理算法。后来移植到支持 SVE2 的核上,发现向量化程度不够。SVE2 的编程模型和 NEON 完全不同,建议尽早用 arm_sve.h 头文件做开发。

1.2.2 CCA:机密计算架构

CCA 是 v9 在安全领域的杀手锏。TrustZone 把世界分成安全和非安全两个世界,但 CCA 更进一步——它允许在非安全世界中创建多个领域(Realm)。

每个 Realm 就像一个黑盒子。操作系统看不到 Realm 里的内容,Hypervisor 也看不到。只有 Realm 自己知道自己在干什么。

  • 动态创建:Realm 可以在运行时创建和销毁。
  • 硬件隔离:基于页表的二级地址转换,加上内存加密。
  • 远程证明:Realm 可以向远程客户端证明自己的身份和完整性。

注意:CCA 需要硬件支持。目前只有 ARMv9.2 以上的核心才完整支持 CCA。如果你的芯片是 v9.0,只能使用 TrustZone,没有 Realm 功能。

1.2.3 52 位虚拟地址空间

这个特性其实 v8.2 就有了,但 v9 把它变成了标准配置。52 位虚拟地址意味着什么?

  • 最大虚拟地址空间:2^52 = 4 PB
  • 物理地址同样支持 52 位
  • 页表层级从 3 级变成 4 级(或 5 级)

嗯,这里要注意:52 位地址不是默认开启的。你需要设置 TCR_ELx.TxSZ 字段,并且操作系统要支持大地址空间。我在调试一个数据库缓存系统时,48 位地址不够用,切换到 52 位后,问题迎刃而解。

1.3 AArch64 执行状态详解

AArch64 是 v8/v9 的 64 位执行状态。v9 只保留 AArch64,AArch32 被标记为 deprecated。我个人建议,新项目直接上 AArch64,别回头。

1.3.1 异常等级(Exception Levels)

AArch64 有 4 个异常等级,从 EL0 到 EL3。每个等级有独立的寄存器组和权限。

异常等级 运行模式 典型软件 权限
EL0 用户态 应用程序 最低,不能访问系统寄存器
EL1 内核态 操作系统内核 可管理内存、中断、进程
EL2 Hypervisor 态 虚拟机监视器 虚拟化扩展,控制虚拟机
EL3 安全监控态 Secure Monitor 最高,控制安全状态切换

你想想看,这种分层设计让安全隔离变得非常自然。EL3 管安全,EL2 管虚拟化,EL1 管操作系统,EL0 跑应用。每一层都只能看到自己该看的东西。

1.3.2 寄存器模型

AArch64 有 31 个通用寄存器,X0-X30。每个都是 64 位。还有一堆系统寄存器,以 _ELx 结尾,表示它们属于哪个异常等级。

// 读取当前异常等级
mrs x0, CurrentEL
// x0 的低两位表示当前 EL
// 0b00 = EL0, 0b01 = EL1, 0b10 = EL2, 0b11 = EL3

// 设置中断掩码
msr DAIFSet, #0x0F  // 屏蔽所有中断

我记得刚开始写 AArch64 汇编时,最不习惯的就是系统寄存器的命名。比如 TTBR0_EL1 是 EL1 的页表基址寄存器,TTBR0_EL2 是 EL2 的。名字一样,后缀不同,功能完全不同。写错一个,系统直接挂掉。

1.3.3 内存模型与页表

AArch64 使用 4KB 或 64KB 页。页表层级取决于地址宽度和页大小。

  • 4KB 页 + 48 位地址:4 级页表(L0-L3)
  • 4KB 页 + 52 位地址:5 级页表(L0-L4)
  • 64KB 页 + 48 位地址:3 级页表(L0-L2)

页表项(PTE)包含物理地址、权限位、属性位。其中 XN(不可执行)和 PXN(特权不可执行)是安全关键位。我见过一个案例,有人把栈区域设成了可执行,结果被 ROP 攻击利用。所以,永远不要给数据区域设置可执行权限。

经验之谈:调试页表问题,我推荐用 readelf -l 查看段权限,用 cat /proc/self/maps 看进程地址空间。如果发现 rwx 的段,十有八九是配置错了。

1.4 ARMv9 知识体系总览

下面这张 SVG 图,把 v9 的核心知识点串起来了。你可以把它当作本章的思维导图。

ARMv9 架构知识体系总览 ARMv9 架构 SVE2 向量扩展 CCA 机密计算 AArch64 执行状态 向量长度可变 谓词执行 Realm 管理 远程证明 异常等级 EL0-EL3 寄存器模型 v9 向下兼容 v8,但新增特性(SVE2、CCA、52位地址)需要硬件和软件同时支持 新项目建议直接基于 ARMv9.2 及以上版本开发

1.5 从 v8 迁移到 v9:你需要知道的事

如果你手头有 v8 的项目要迁移到 v9,我建议你关注以下几点:

  1. 检查编译器支持:GCC 10+、LLVM 11+ 才支持 SVE2 和 CCA 指令。
  2. 更新启动代码:v9 的异常向量表格式和 v8 略有不同,主要是新增了 SError 同步异常的处理。
  3. 重新配置 MMU:如果要用 52 位地址,页表层级和 TCR_ELx 必须重新设置。
  4. 安全固件升级:CCA 需要 EL3 固件支持,建议使用 TF-A 2.6+ 版本。

重要提醒:不要以为 v8 的代码直接编译就能在 v9 上获得性能提升。SVE2 的向量化需要手动改写代码。我见过一个团队,把 v8 的 NEON 代码直接编译到 v9 上跑,性能反而下降了——因为编译器自动生成了 SVE2 指令,但数据布局没优化,导致 cache miss 严重。

1.6 本章小结

ARMv9 不是小修小补,而是面向未来十年的架构。SVE2 解决了向量化编程的碎片化问题,CCA 重新定义了云原生安全,AArch64 则统一了 64 位生态。

我个人觉得,v9 最值得投入精力的两个方向是:SVE2 的向量化优化和CCA 的 Realm 开发。前者能直接提升计算性能,后者能让你在安全领域建立技术壁垒。

好了,第一章就到这里。记住这张知识体系图,后面每一章都会围绕它展开。