工具准备

  • arm-linux-gnueabi-as: 可以通过下载 linaro 工具链获取
  • qemu-system-arm

程序范例

创建test.c,内容如下

volatile unsigned int *const UART0DR = (unsigned int *)0x101f1000;

void print_uart0(const char *s)
{
        while (*s) {
                *UART0DR = (unsigned int)(*s);
                s++;
        }
}

void c_entry()
{
        print_uart0("Hello World\n");
}

创建startup.S文件,内容如下

.global _Reset
_Reset:
        ldr sp, =stack_top
        bl c_entry
        b .

因为是在裸板运行,所以需要设置程序入口点、栈起始地址等,通过test.lds链接脚本设置,内容如下:

ENTRY(_Reset)
SECTIONS
{
        . = 0x10000;
        .startup . : { startup.o(.text) }
        .text : { *(.text) }
        .data : { *(.data) }
        .bss : { *(.bss COMMON) }
        . = ALIGN(8);
        . = . + 0x1000;
        stack_top = .;
}

使用交叉编译工具链编译并基于 qemu 运行

$ arm-linux-gnueabi-as -mcpu=arm926ej-s -g startup.S -o startup.o
$ arm-linux-gnueabi-gcc -c -mcpu=arm926ej-s -g test.c -o test.o
$ arm-linux-gnueabi-ld -T test.lds test.o startup.o -o test.elf
$ arm-linux-gnueabi-objcopy -O binary test.elf test.bin
$ qemu-system-arm -M versatilepb -m 128M -nographic -kernel test.bin # 通过 Ctrl+A 然后按 x 退出 qemu

参考