Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cleanly exit QEMU after executing bare metal program without user intervention?

I am assembling a cross compiling unit testing rig for an ARM system and running the tests on a host machine with qemu-system-arm. Specifically, I'm using qemu to emulate the Stellaris LM3S6965 eval board as it contains a Cortex M3 processor like my target environment. The binary run in qemu is built with GNU Tools for ARM.

There is no OS involved. The test suite is run as a bare metal application with qemu in -nographic mode. The toolchain and the test rig itself are working fine. And the tests successfully run to completion and produce test results within qemu just fine as well.

The problem is in wrapping up qemu in an automated build tool (Rake in this case). Other than keyboard commands I have not yet found a good way to cause qemu to exit after the test suite runs and spits out its results. This causes the build environment to hang / rely on user intervention.

I have looked high and low and have found no good sources on how to accomplish a simple exit after program termination. I did find a couple suggestions of running qemu with the -no-reboot option and then triggering a system reset from the program running in the emulator. I have tried this. It works… kinda. I write the appropriate values to the emulated processor's reset vector after main() executes, and this does trigger a reset. After running the test suite qemu reports catching a system reset. However, it reports this as a hardware error, dumps register contents, and then exits angry (error message below). While this does accomplish exiting after the test suite runs, it then breaks the automated build script due to qemu exiting with an error condition.

qemu: hardware error: System reset

I'd like to avoid hacking the insertion of keyboard commands into the build to simulate user intervention. I'd also like to avoid relying on qemu exiting in an error state.

It seems I'm close to a clean exit but not quite there. Searching for the qemu error message (above) has produced no relevant documentation other than tangentially related bug reports.

Is there a mechanism for causing qemu to exit after main() returns in a bare metal program that I'm missing? Will this -no-reboot + system reset strategy work? If so, what else is necessary to allow qemu to exit cleanly?

like image 939
Michael Karlesky Avatar asked Aug 13 '15 14:08

Michael Karlesky


People also ask

How do you break out of qemu?

If you are running in graphics mode, then from the ctrl-alt-2 qemu window, type "quit" after "Power down" to exit the qemu process.

Can qemu emulate arm on x86?

QEMU can emulate both 32-bit and 64-bit Arm CPUs.


1 Answers

I recommend to use Angel interface for ARM processores. It is very helpful for debugging. You can read something about it on ARM Info Center. Especially look at operation angel_SWIreason_ReportException (0x18) and parameter ADP_Stopped_ApplicationExit to which QEMU will understand that your application has ended.

Don't forget to run QEMU with -semihosting argument, like this:

qemu-system-arm -nographic -semihosting -kernel your_binary

Here is the code to tell QEMU to stop (you have to use some assembler):

register int reg0 asm("r0");
register int reg1 asm("r1");

reg0 = 0x18;    // angel_SWIreason_ReportException
reg1 = 0x20026; // ADP_Stopped_ApplicationExit

asm("svc 0x00123456");  // make semihosting call

You can also look at my project at github where I used it.

like image 159
J. Havran Avatar answered Oct 13 '22 05:10

J. Havran