如何在qemu上运行 arm64 baremetal hello world程序?

How to run arm64 baremetal hello world program on qemu?

通常一个问题会引出另一个问题。
在尝试调试内联汇编代码时,我遇到了另一个基本问题。
长话短说,我想在 qemu 上 运行 arm64 baremetal hello world 程序。

#include <stdio.h>

int main()
{
printf("Hello World!\n");
}

我是这样编译的: aarch64-none-elf-gcc -g test.c

我得到 _exit _sbrk _write _close _lseek _read _fstat 和 [=21 的未定义引用错误=].我过去了解到 -specs=rdimon.specs 编译选项可以消除此错误。 所以我运行

aarch64-none-elf-gcc -g test.c -specs=rdimon.specs

它可以用 a.out 文件编译。
现在我运行 qemu baremetal 程序来调试代码。

qemu-system-aarch64 -machine virt,gic-version=max,secure=true,virtualization=true -cpu cortex-a72 -kernel a.out -m 2048M -nographic -s -S

这里是 gdb 运行 结果。

ckim@ckim-ubuntu:~/testdir/testinlinedebugprint$ aarch64-none-elf-gdb a.out
GNU gdb (GNU Toolchain for the A-profile Architecture 10.2-2020.11 (arm-10.16)) 10.1.90.20201028-git
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=aarch64-none-elf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://bugs.linaro.org/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...
(gdb) set architecture aarch64
The target architecture is set to "aarch64".
(gdb) set serial baud 115200
(gdb) target remote :1234
Remote debugging using :1234
_start ()
    at /tmp/dgboter/bbs/build02--cen7x86_64/buildbot/cen7x86_64--aarch64-none-elf/build/src/newlib-cygwin/libgloss/aarch64/crt0.S:90
90  /tmp/dgboter/bbs/build02--cen7x86_64/buildbot/cen7x86_64--aarch64-none-elf/build/src/newlib-cygwin/libgloss/aarch64/crt0.S: No such file or directory.
(gdb) b main
Breakpoint 1 at 0x4002f8: file test.c, line 26.
(gdb) 
(gdb) r
The "remote" target does not support "run".  Try "help target" or "continue".
(gdb) c
Continuing.

它不会破裂和挂起。
我究竟做错了什么?我该如何解决 /tmp/dgboter/bbs/build02--cen7x86_64/buildbot/cen7x86_64--aarch64-none-elf/build/src/newlib-cygwin/libgloss/aarch64/crt0.S: No such file or directory. 问题? 任何帮助将不胜感激。谢谢!

添加:
我意识到我之前问过同样的问题()(啊!我的记忆..)我意识到我需要所有的东西,比如 start.S crt0.S 和链接器脚本,. . .我愚蠢地认为 baremetal 编译器会自动处理它,而实际上我必须填充真正低级的东西。在某些情况下,我曾在裸机程序上工作过,但那是在其他人已经设置了这些初始环境之后(有时我什至修改了它们很多次!)。在裸机中,你必须提供所有的东西。 g运行ted 没有什么可以接受的,因为它是“裸机”。我这么晚才意识到这个基本的东西..

当您为“裸机”构建程序时,这意味着您需要配置您的工具链以生成可在您尝试 运行 它的特定裸机上运行的二进制文件。例如,二进制文件必须:

  • 将其代码放在机器内存映射中有 ROM 或 RAM 的地方
  • 将其数据放在有 RAM 的地方
  • 确保在启动时正确初始化堆栈指针以指向 RAM
  • 如果要打印输出,请包括访问该机器上合适设备的例程。这很可能是串口,而串口通常是完全不同的设备,位于不同的地址,不同的机器上

如果其中任何一项有误或与您 运行 所用的实际机器不匹配,结果通常就是您所看到的——程序崩溃而没有输出。

更具体地说,rdimon.specs 告诉编译器构建 C 库函数,这些函数通过“半主机”调试器 ABI(它支持“打印字符串”和其他一些东西)来执行其中的一些操作。您的 QEMU 命令行不启用半主机的实现(您可以使用 -semihosting 选项打开它),因此根本不起作用。但是您可能还遇到了其他问题。