QEMU无法运行ARM裸机EABI二进制文件的原因及解决方法
问题描述
我需要追踪一款裸机应用执行的机器指令,项目采用搭载Cortex-M4(ARMv7架构)的STM32 Discovery开发板。由于QEMU不支持该特定开发板,我尝试执行命令:
qemu-system-arm -M ast1030-evb -cpu cortex-m4 -m 128M -nographic -kernel build/setup_heap_lab.bin
其中build/setup_heap_lab.bin是通常烧录到开发板的编译后二进制文件,ast1030-evb为选用的虚拟机。QEMU支持的Cortex-M4虚拟机如下:
[alessandro@commodoroII setup_heap_lab]$ qemu-system-arm -M help | grep -i m4 ast1030-evb Aspeed AST1030 MiniBMC (Cortex-M4) mps2-an386 ARM MPS2 with AN386 FPGA image for Cortex-M4 netduinoplus2 Netduino Plus 2 Machine (Cortex-M4) olimex-stm32-h405 Olimex STM32-H405 (Cortex-M4)
但启动QEMU时出现错误:
[alessandro@commodoroII setup_heap_lab]$ qemu-system-arm -M ast1030-evb -cpu cortex-m4 -m 128M -nographic -kernel build/setup_heap_lab.bin qemu-system-arm: ../qemu-8.0.2/target/arm/cpu.h:2396: arm_is_secure_below_el3: Assertion `!arm_feature(env, ARM_FEATURE_M)' failed. Aborted (core dumped)
报错原因
你推测的CPU执行级别问题是正确的。Cortex-M系列属于ARMv7-M架构,它的执行模型基于特权级(Handler/Thread),而非A/R系列的Exception Level(EL0-EL3)。ast1030-evb虚拟机的硬件设计中,QEMU会尝试启用EL3相关的安全状态逻辑,但Cortex-M4不支持EL层级,触发了代码中的断言检查!arm_feature(env, ARM_FEATURE_M)——这个断言用于确保处理EL3以下安全状态时,当前CPU不是M系列内核,最终导致程序崩溃。
另外,你指定的-m 128M参数也不合理:Cortex-M4的寻址空间通常远小于128MB,且ast1030-evb这类板卡的内存配置无需手动指定,QEMU会自动加载板卡默认参数。
解决办法
更换兼容的QEMU虚拟机:选择专为Cortex-M设计、不涉及EL层级的虚拟机,比如
mps2-an386或olimex-stm32-h405。优先推荐mps2-an386,它是ARM官方的MPS2平台,对Cortex-M4的支持更通用。修改后的启动命令示例:qemu-system-arm -M mps2-an386 -cpu cortex-m4 -nographic -kernel build/setup_heap_lab.bin适配二进制文件的内存布局:如果更换虚拟机后仍无法运行,可能是你的裸机程序针对STM32的内存布局(如起始地址、中断向量表)编译,需调整链接脚本,将程序入口和内存映射改为目标QEMU虚拟机的配置。比如
mps2-an386的默认Flash起始地址为0x00000000,RAM起始地址为0x20000000,若你的STM32程序使用类似地址,可能无需修改;若差异较大,需调整链接脚本中的MEMORY段和ENTRY配置。去掉多余的内存参数:删除
-m 128M参数,让QEMU使用板卡默认的内存配置,避免因参数不匹配引发额外问题。
内容的提问来源于stack exchange,提问作者Alessandro Bertulli

