RK3588上的aarch64异常等级切换:不是理论,是每一纳秒都在发生的硬件事实
你有没有在RK3588上调试过一个“莫名其妙”的ESR_EL2错误?
比如EC=0x1A(系统寄存器访问陷阱),但Guest明明没动SCTLR_EL1——结果发现是U-Boot启动时漏配了HCR_EL2.TGE,导致Linux内核的msr指令被KVM误判为敏感操作;
又或者,OP-TEE TA调用smc #0后卡死,JTAG抓到SPSR_EL3.M = 0x04(EL0模式),而eret却试图从EL3返回EL0——这根本不可能发生,CPU当场进入UNDEFINED状态。
这些不是教科书里的假设场景。它们就发生在RK3588开发板通电后的第83毫秒、在YOLOv5模型第一次读取ISP帧缓冲区时、在车载CAN总线发出第一帧诊断报文的瞬间。aarch64异常等级切换不是一种“机制”,而是RK3588芯片里真实流动的电流路径、被硬连线控制的寄存器门控、以及每一条smc/hvc/svc指令触发的物理状态跃迁。
下面,我们不讲概念,不列标准,只说RK3588上真正跑起来的东西。
四层特权:不是分层设计图,而是四套独立的CPU“操作系统”
ARMv8-A定义EL0–EL3,并非为了画一张漂亮的架构图。它本质是给同一颗Cortex-A76核心,配置了四套完全隔离的运行环境——就像在同一台物理服务器上同时运行四个互不通信的操作系统镜像,但这个隔离不是靠软件模拟,而是由CPU微架构直接实现。
| 特性 | EL0(用户) | EL1(内核) | EL2(Hypervisor) | EL3(Secure Monitor) |
|---|---|---|---|---|
| 栈指针寄存器 | SP_EL0 | SP_EL1 | SP_EL2 | SP_EL3 |
| 当前特权等级位 | SPSR_EL0.M[4:0] = 0b00000 | SPSR_EL1.M[4:0] = 0b0101 | SPSR_EL2.M[4:0] = 0b1010 | SPSR_EL3.M[4:0] = 0b1111 |
| 向量表基址 | 不可用(无VBAR_EL0) | VBAR_EL1(通常0xffff0000) |