1. 课程导入
各位好,欢迎来到《ARMv8性能调优与安全扩展调试实战》的第一章。咱们今天不绕弯子,直接聊聊ARMv8最核心的几个概念。说实话,我刚开始接触ARMv8的时候,也被那一堆新名词搞得有点晕。但后来发现,只要把执行状态、异常等级和寄存器组这三块吃透了,后面看什么都顺眼。
1.1 两种执行状态:AArch64与AArch32
ARMv8最大的变化,就是引入了AArch64执行状态。这不是简单的"32位升级到64位",而是整个架构的重新设计。
| 特性 | AArch64 | AArch32 |
|---|---|---|
| 寄存器宽度 | 64位通用寄存器 | 32位通用寄存器 |
| 指令集 | A64(固定32位长度) | A32/T32(32位/16位混合) |
| 异常等级 | EL0~EL3,共4级 | PL0~PL3,共4级(但映射方式不同) |
| 地址空间 | 最大48位虚拟地址 | 最大32位虚拟地址 |
| 兼容性 | 不向后兼容AArch32 | 兼容ARMv7及之前 |
关键点:AArch64和AArch32是两种互斥的执行状态。处理器在复位时可以选择进入哪一种,但运行时不能在同一异常等级下混用。不过,不同异常等级可以运行不同的执行状态——比如EL3跑AArch64,EL0跑AArch32,这是完全允许的。
我个人习惯把AArch64看作一个"全新的起点"。它抛弃了ARMv7时代很多历史包袱,比如条件执行(除了分支指令)、LDM/STM这种批量加载存储指令,都砍掉了。为什么?为了简化硬件设计,提高频率。你想想看,一个指令里带4个条件位,解码器得多复杂。
1.2 异常等级模型:EL0到EL3
ARMv8的异常等级模型,说白了就是给软件划分了四个"权限层级"。
- EL0:用户态。跑应用程序,权限最低。不能直接操作硬件,不能配置MMU,连中断都碰不到。
- EL1:操作系统内核态。Linux内核、RTOS都跑在这里。可以管理MMU、处理中断、调度任务。
- EL2:虚拟机监视器(Hypervisor)。虚拟化场景下,Host VM跑在这里。我做过一个项目,需要在EL2拦截Guest OS对定时器的访问,那叫一个折腾。
- EL3:安全监视器(Secure Monitor)。这是最高权限等级,负责安全世界和普通世界的切换。ARM TrustZone的根就在EL3。
避坑指南:我曾经在调试一个安全启动方案时,发现EL3的代码里不小心访问了EL2的寄存器,结果直接触发SError异常。记住:高等级可以访问低等级的资源,反过来不行。EL3能看EL2的配置,但EL2想读EL3的寄存器?门都没有。
异常等级之间通过异常来切换。比如应用程序(EL0)调用系统调用(SVC指令),就会触发一个同步异常,处理器提升到EL1,跳转到内核的异常向量表。这个过程涉及栈切换、寄存器保存、异常返回地址记录——嗯,细节后面章节会展开。
1.3 寄存器组概览
AArch64的寄存器组,比AArch32规整得多。咱们先看通用寄存器。
1.3.1 通用寄存器:X0~X30
AArch64有31个通用寄存器,X0到X30。每个都是64位宽。访问低32位时,用W0~W30。比如:
// 64位操作
ADD X0, X1, X2 // X0 = X1 + X2
// 32位操作(高位自动清零)
ADD W0, W1, W2 // W0 = W1 + W2,X0的高32位清零
这里有个细节:X30是链接寄存器(LR),保存函数调用的返回地址。X29是帧指针(FP),用于栈回溯。X18是平台寄存器,一般不用,留给平台固件用。
注意:X0~X7用于传递参数和返回值。函数调用时,前8个参数放X0~X7,多余的压栈。返回值放X0。这是ARM64的调用约定(AAPCS64),写汇编时千万别搞混。
1.3.2 特殊寄存器
除了通用寄存器,还有一堆特殊寄存器。我挑几个最常用的说说:
- SP_ELx:栈指针。每个异常等级有自己的栈指针。EL1用SP_EL1,EL2用SP_EL2,EL3用SP_EL3。EL0的栈指针是SP_EL0。
- ELR_ELx:异常返回地址寄存器。发生异常时,处理器把返回地址存到这里。ERET指令就从这里恢复执行。
- SPSR_ELx:保存的程序状态寄存器。异常发生时,PSTATE(处理器状态)被保存到这里。包括条件标志位、异常掩码、执行状态等。
- VBAR_ELx:异常向量基地址寄存器。指向异常向量表的起始地址。每个异常等级有自己的向量表。
1.3.3 系统寄存器访问
访问系统寄存器,必须用MSR和MRS指令。不能像通用寄存器那样直接MOV。
// 读取当前异常等级
MRS X0, CurrentEL
// 设置VBAR_EL1
LDR X0, =my_vector_table
MSR VBAR_EL1, X0
// 写SPSR_EL1
MSR SPSR_EL1, X0
我记得刚学ARMv8时,总想用STR写系统寄存器,结果编译直接报错。后来养成了习惯:看到"系统寄存器"四个字,脑子里自动弹出MSR/MRS。
1.4 知识结构图:ARMv8核心概念关系
下面这张图,把执行状态、异常等级和寄存器组的关系串起来了。建议保存下来,后面章节会反复用到。
1.5 本章小结
这一章我们覆盖了三个核心概念:
- AArch64 vs AArch32:两种执行状态,互斥但可共存于不同异常等级。
- EL0~EL3:四个异常等级,从用户态到安全监视器,权限逐级递增。
- 寄存器组:31个通用寄存器(X0~X30)加一堆特殊寄存器,用MSR/MRS访问。