The Codesourcery tools can be used to generate cortex-m3 binaries that can be simulated in a "semi-hosted" environment provided by Qemu. Qemu supports many cpu models; unfortunately, the default installation on OS X (using MacPorts) doesn't provide an ARM model. To install the necessary model with MacPorts

   > sudo port install qemu +target_arm

If you've previously installed Qemu with MacPorts, you'll need to uninstall it.

Compiling for the semi-hosted environment requires some libraries and linker scripts that are not included with the Codesourcery sources. I downloaded a Linux binary and copied the necessary libraries and scripts to my OS X installation. I haven't yet scripted this. Copy all of the libraries (*.a) and linker scripts (*.ld) from the directory tree

  arm-none-eabi/lib

from within the binary distribution to your OS X installation (skipping those you already have).

Create a simple test program (main.c)

  #include <stdio.h>

  int main()
  {
     printf("hello world\n");
  }

Compile with the appropriate flags

 arm-none-eabi -o main.elf main.c -g -mcpu=cortex-m3 -mthumb -T generic-hosted.ld

The "-mcpu=cortex-m3 -mthumb" flags ensure our codes is for a cortex-m3 compiler. "-T generic-hosted.ld" uses the "appropriate" linker script. A peak inside this script (in the arm-none-eabi/lib toolchain directory), reveals that it causes the appropriate libraries and startup code to be linked into our object code. "Appropriate" in this context means with key system calls implemented as software interrupts.

Now you can execute in Qemu

 qemu-system-arm  -cpu cortex-m3 -nographic -monitor null -serial null -semihosting -kernel main.elf

Which should behave as expected. The "-nographic -monitor null -serial null" disable features of qemu which we neither need nor want in this application. "-semihosting" implements the "ANGEL" software interrupts for system calls as originally developed for the ARMULATOR simluator from ARM. "-cpu cortex-m3" is the option for simulation a cortex-m3 processor. Finally "-kernel main.elf" tells qemu to execute directly from our object file.

It is also possible to attach gdb to qemu (you'll need two windows):

  1. qemu-system-arm -cpu cortex-m3 -nographic -monitor null -serial null -semihosting -kernel main.elf -gdb tcp::51234 -S
  2. arm-none-eabi-gdb main.elf

"51234" is simply a tcp port number chosen randomly. Within gdb execute the following commands:

   (gdb) target remote localhost:51234
   (gdb) load
   (gdb) break main
   (gdb) continue

Note: I found the directions here http://balau82.wordpress.com/2010/11/04/qemu-arm-semihosting/ helpful; however, I found some issues.

  1. Using the elf file directly makes it unnecessary to create the special ld script
  2. To simulate cortex-m3 programs additional flags are needed as provided above

The following is also helpful : http://dc0d32.blogspot.com/2010/03/debugging-kernel-with-qemu-and-gdb.html