Reputation: 1557
I am running the qemu-arm
user space emulator inside of a Docker container on Docker for Mac.
I am working on a code base that runs on cortex-m4 processors. I want to be able to cross-compile the code in the docker container to target the cortex-m4 processor and run that code on the qemu-arm
user space emulator.
to test this, I have a simple C program (/tmp/program.c
):
int main() {
return 0;
}
I use the debian:stable docker image as a base.
I compile the program with the GNU arm toolchain like so:
arm-none-eabi-gcc -mcpu=cortex-m4 --specs=nosys.specs /tmp/program.c
Then I attempt to run this with qemu-arm
in the docker container:
qemu-arm -cpu cortex-m4 -strace ./a.out
But I get the following error:
--- SIGSEGV {si_signo=SIGSEGV, si_code=1, si_addr=0x0007fff0} ---
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
Segmentation fault
From what I understand, SIGSEGV
occurs in a few scenarios, the only one that makes sense here is that I am accessing memory that I don't have access to when I attempt to run the binary in the qemu-arm
user space.
It would seem that the si_addr=0x0007fff0
is the address that I am accessing that I am not supposed to.
Since my program does very little, I am assuming this inaccessible address might be where qemu-arm
is attempting to store the binary to run? But I don't see an option in qemu-arm
to specify this.
So my questions are:
qemu-arm
is attempting to store the binary to be run), is there a way to change that? I didn't see one in any of the command line optionsDocker version 20.10.6, build 370c289
Dockerfile to reproduce:
FROM debian:stable
RUN apt-get update
RUN apt-get install -y gcc-arm-none-eabi qemu-user gcc
RUN echo 'int main() {return 0;}' > /tmp/program.c
# running the program on the docker container exits successfully
RUN gcc /tmp/program.c
RUN ./a.out
# running the program in `qemu-arm` errors
RUN arm-none-eabi-gcc -mcpu=cortex-m4 --specs=nosys.specs /tmp/program.c
RUN qemu-arm -cpu cortex-m4 -strace ./a.out
Upvotes: 0
Views: 1078
Reputation: 11383
qemu-arm is an emulator for Linux user-space binaries. The program you're compiling seems to be built with a bare-metal toolchain. It's not impossible to compile a bare-metal binary in such a way that it will run as a Linux user-space program as well, but you have to take specific steps to make it work that way.
You should probably think about whether what you really wanted was:
For example, how are you expecting your program to produce output? Is the program going to want to talk directly to (emulated) hardware like a serial port, or to other devices? Does the program need to run interrupt handlers?
The best way to debug what's happening is to get QEMU to start its gdbstub, and connect an arm-aware gdb to it. Then you can single step through. (This will probably be a confusing introduction to your toolchain's C runtime startup code...)
Upvotes: 1