c++ - 如何在 ARM 上运行 HelloWorld

标签 c++ arm qemu

我需要在 arm 上运行 HelloWorld。 我启动:

$ arm-none-eabi-g++ -mthumb -mcpu=cortex-m3 -c test.cpp -o test

$ file test
test: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), not stripped

$  qemu-arm test <br>
Error while loading test: Permission denied

最佳答案

qemu-system-arm -machine help
...
lm3s811evb           Stellaris LM3S811EVB
...

来自 lm3s811 数据表或查看 qemu arm 硬件上的 stellaris 后端的源代码。 Uart0 基地址为 0x4000C000,数据(rx 和 tx)寄存器偏移量为 0x000。根据经验,qemu 后端往往不会为 tx 缓冲区忙碌而烦恼......

闪光.s

.cpu cortex-m0
.thumb

.thumb_func
.global _start
_start:
    .word 0x20001000
    .word reset
    .word hang
    .word hang
    .word hang
    .word hang
    .word hang

.thumb_func
reset:
    bl notmain
    b hang

.thumb_func
hang:   b .

.thumb_func
.globl PUT32
PUT32:
    str r1,[r0]
    bx lr

uart01.c

void PUT32 ( unsigned int, unsigned int );
#define UART0BASE 0x4000C000
int notmain ( void )
{
    unsigned int rx;
    for(rx=0;rx<7;rx++)
    {
        PUT32(UART0BASE+0x00,0x30+rx);
    }
    return(0);
}

flash.ld

MEMORY
{
    rom : ORIGIN = 0x00000000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > rom
    .rodata : { *(.rodata*) } > rom 
    .bss : { *(.bss*) } > ram
}

是的,stellaris 是您可以购买的第一个硅片 cortex-m3,我指定了 cortex-m0。基本上阻止了 thumb2 扩展,或者其中的大部分。更便携,可以根据需要轻松更改。

arm-none-eabi-as --warn -mcpu=cortex-m0 flash.s -o flash.o
arm-none-eabi-gcc -Wall -O2 -nostdlib -nostartfiles -ffreestanding  -mcpu=cortex-m0 -mthumb -c uart01.c -o uart01.o
arm-none-eabi-ld -o uart01.elf -T flash.ld flash.o uart01.o
arm-none-eabi-objdump -D uart01.elf > uart01.list
arm-none-eabi-objcopy uart01.elf uart01.bin -O binary

然后

qemu-system-arm -M lm3s811evb -m 16K -nographic -kernel uart01.bin

输出是

0123456

ctrl-a 然后按 x 退出 qemu。或

qemu-system-arm -M lm3s811evb -m 16K -kernel uart01.bin

然后按 ctrl-alt-3(3 而不是 F3),串行控制台会弹出串行输出。当您关闭串行控制台时,qemu 将关闭。

我想记住有人告诉我 qemu cortex-m3 支持不是很好。

正常的arm内核应该被很好地测试,因为它们被用来交叉编译各种arm目标板。不确定到底哪些内核经过了很好的测试,但如果你像 ARM 一样启动,你可以做拇指的东西,但剩下的用拇指做,用

启动
.globl _start
_start:
    b reset
    b hang
    b hang
    b hang
reset:
    mov sp,#0x20000
    bl notmain
hang:
    b hang

机器

versatilepb          ARM Versatile/PB (ARM926EJ-S)

它的 uart 在 0x101f1000,所以

for(ra=0;;ra++)
{
    ra&=7;
    PUT32(0x101f1000,0x30+ra);
}

可以用

构建你的应用

arm-none-eabi-gcc -Wall -O2 -nostdlib -nostartfiles -ffreestanding -mcpu=arm7tdmi -mthumb -c uart01.c -o uart01.o

将您的链接描述文件更改为全部基于 ram。

MEMORY
{
    ram  : ORIGIN = 0x00000000, LENGTH = 32K
}

SECTIONS
{
   .text : { *(.text*) } > ram
   .bss  : { *(.text*) } > ram
}

然后

qemu-system-arm -M versatilepb -m 128M -nographic -kernel hello.bin

(嗯,这个加载是在 0x0000 还是 0x8000?应该不难理解)

你可以得到 cortex-m 的大部分拇指感觉(m0 基本上不是 m3,你可以找到一个 armv7-a 机器你可能可以运行 thumb2 构建的代码(仍然像 arm 不是 cortex-m 的 Boot ) ).例如

realview-pb-a8       ARM RealView Platform Baseboard for Cortex-A8

可能几乎可以按原样使用 newlib,需要更改 crt0.s 或现在所谓的任何名称才能像 arm 而不是 cortex-m 一样启动。其余部分可以使用 armv7m 构建,理论上可以工作。

或者从 stellaris 开始,无论你的真正目标是什么,只要你自己的硬件支持,如果/当你发现问题时修复 cortex-m3 内核。

关于c++ - 如何在 ARM 上运行 HelloWorld,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42371788/

相关文章:

c++ - 如何通过shell杀死父进程和子进程?

c - 带有 objcopy 的巨大二进制文件

arm - 如何为 ARM 编译 VLC

linux-kernel - 远程 gdb 调试不会在断点处停止

c++ - 简单的拼写检查算法

c++ - 没有正确关闭任务栏关闭事件

c - sprintf 在 32 位 MCU 中通过中断重新进入 64 位操作

c - 为什么将 char 传递给函数会改变它在 c 中的值?

timestamp - qemu中执行 block 的时间

c++ - 在 UMFPACK 中,我们需要多久进行一次符号和数值分解?