QEMU树莓派3B裸机启动SCR_EL3寄存器配置疑问
QEMU树莓派3B裸机启动SCR_EL3配置疑问解答
疑问1:不启用SCR_EL3的HCE位,start_el2末尾的eret指令无法正常工作的原因
SCR_EL3的HCE(Hypervisor Call Enable)位负责启用EL2的虚拟化功能。当该位为0时,EL2处于非活跃状态,ARM架构不允许EL2执行特权级切换操作——也就是无法通过eret从EL2返回至EL1。此时执行eret会触发未定义异常,直接中断启动流程。代码中从EL3进入EL2后需要切换到EL1完成初始化,必须开启HCE位让EL2具备虚拟化切换的权限。
疑问2:将NS位设为0时无法正常工作,安全模式为何阻塞eret?
SCR_EL3的NS(Non-Secure)位控制进入安全状态(NS=0)还是非安全状态(NS=1)。虽然安全模式理论上拥有更高的内存访问权限,但它依赖完整的安全环境支撑:
- 树莓派3B(及QEMU模拟环境)默认未初始化安全世界的基础配置,比如安全状态下的异常向量表、内存分区、安全监控模式(SMC)的处理逻辑等;
- 代码完全没有针对安全状态做适配,既未配置安全EL1的相关寄存器,也未设置安全内存映射,此时从安全态EL2执行
eret返回安全态EL1时,会因缺少必要的安全环境触发异常,导致启动失败。
疑问3:代码中设置了RES保留位的原因
代码注释中标注的RES保留位,大概率是以下两种情况:
- 注释错误:
0x5b1对应的二进制位中,存在代码作者误判为保留的功能位。比如bit3或bit5,在标准ARM架构文档中可能被标记为保留,但QEMU对树莓派3B的模拟未严格校验这些位,设置后不会触发异常; - 测试遗留:代码作者在调试时发现设置这些位不影响启动流程,便保留了下来。标准ARM架构要求保留位必须设为0,但QEMU的宽松模拟允许非合规设置,因此不会导致运行错误。
附相关汇编代码
_start: // in QEMU all of 4 ARM CPUs are started simultaneously // by default. I don't know if this is the real hw behaviour, // but here I jump to halt if CPU ID (stored in MPIDR // register, first 2 bits) is not 0 mrs x1, mpidr_el1 and x1, x1, #3 cmp x1, #0 bne hang // address for stack pointer ldr x1, =_start // drop to EL2 mov x2, #0x5b1 // RW=1, HCE=1, SMD=1, RES=1, NS=1 msr scr_el3, x2 mov x2, #0x3c9 // D=1, A=1, I=1, F=1 M=EL2h msr spsr_el3, x2 adr x2, start_el2 msr elr_el3, x2 eret start_el2: // set sp in EL1 msr sp_el1, x1 // enable AArch64 in EL1 mov x0, #(1 << 31) // AArch64 orr x0, x0, #(1 << 1) // SWIO hardwired on Pi3 msr hcr_el2, x0 mrs x0, hcr_el2 // set vector address in EL1. ldr x0, =vector msr vbar_el1, x0 // change execution level to EL1 mov x2, #0x3c4 // D=1, A=1, I=1, F=1 M=EL1t msr spsr_el2, x2 adr x2, start_el1 msr elr_el2, x2 eret start_el1: // set sp mov sp, x1 // Clear bss. ldr x1, =__bss_start ldr w2, =__bss_size 1: cbz w2, 2f str xzr, [x1], #8 sub w2, w2, #1 cbnz w2, 1b 2: bl main
内容的提问来源于stack exchange,提问作者Angel Ruiz
相关产品推荐
相关产品推荐

