Search code examples
armemulationtraceqemuexecution

Why QEMU refuses to run this eabi (bare metal) ARM binary?


I need to get a trace of the machine instructions executed by a bare metal application. I use a STM32 Discovery board for my project, which uses a Cortex-M4 and ARMv7. I want to use QEMU, but it doesn't support my specific board, so I tried:

qemu-system-arm -M ast1030-evb -cpu cortex-m4 -m 128M -nographic -kernel build/setup_heap_lab.bin

where build/setup_heap_lab.bin is the compiled binary (which usually I flash on the board), and ast1030-evb is the virtual machine. Note that QEMU seems to support only these Cortex-M4 machines:

[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)

When I launch QEMU however I get this:

[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)

Why it is failing? I kinda found out it has to do with the cpu execution levels, but how can I make it run nevertheless?

Thanks!


Solution

  • That assert is a bug in QEMU (https://gitlab.com/qemu-project/qemu/-/issues/1658) which is fixed upstream. The fix will be in the upcoming 8.1 release, and will probably be in a newer 8.0.x stable release if we do another one.

    However, you've probably only run into it because your guest code is crashing (it happens on the "raise an exception" codepath). You're trying to run a bare metal binary for board X on a model of board Y, and in general this doesn't work, because the binary is likely to try to access devices or RAM which don't exist on the board model you're running it on. You need to either use a machine model that matches the binary, or else build the binary for the machine model you're using.