AArch64架构树莓派EL1运行时SP栈指针对齐错误异常排查
问题根本原因
AArch64架构要求栈指针SP在任何用于内存访问的场景下都必须满足16字节对齐,结合你的代码,核心问题有三个:
- EL1的栈指针未初始化:你在启动代码中给SP赋值的操作是在EL2阶段执行的,此时修改的是
SP_EL2寄存器。而你配置SPSR_EL2时设置了M域为0b0100,对应EL1t模式,切到EL1后会自动切换使用SP_EL0寄存器,这个寄存器你完全没有初始化,值是随机的,大概率不满足16字节对齐要求。 - 栈地址设置不合理:你当前把栈顶设为
_start地址,也就是代码段的起始位置,而栈是向下增长的,只要进行压栈操作就会覆盖你的启动代码,同时你也没有保证_start地址是16字节对齐的。 - 你在目标配置中开启了
+strict-align选项,强制要求所有内存访问必须对齐,进一步放大了栈指针对齐问题的影响。
修复方案
- 调整EL1的栈模式,建议改用EL1h模式,修改
SPSR_EL2的赋值为0b1111000101(最后一位改成1,M域为0b0101,对应EL1使用SP_EL1),避免和EL0的栈混用。 - 在进入EL1后的
init_el1函数最开头,先执行汇编指令初始化SP_EL1,注意栈地址要选在不会覆盖代码、数据段的高位内存,且必须16字节对齐,比如你可以在链接脚本中专门定义一个16字节对齐的栈段,把栈顶设为栈段的最高地址。 - 检查链接脚本,确保你使用的栈地址是16字节对齐的,不要直接用未对齐的符号地址作为栈顶。
- 额外优化:不要把栈放在代码段区域,建议在内存中划出一块独立的栈空间,大小至少设置为4KB以上,避免栈溢出覆盖其他数据。
内容的提问来源于stack exchange,提问作者Someone
相关产品推荐
相关产品推荐

