【发布时间】:2021-05-19 17:33:13
【问题描述】:
我正在学习编写裸机 ARM Cortex-A7 固件,以便在带有半主机的 QEMU 上运行。我知道 ARM GCC 有一个名为 newlib 的 libc 实现,它支持常用 libc 函数的半主机。所以我正在尝试让 newlib 也能正常工作。
解决了很多问题,代码终于在QEMU上正常运行了:https://github.com/iNvEr7/qemu-learn/tree/master/semihosting-newlib
(注意:QEMU 5.2.0 似乎有一个错误会导致 newlib 对 HEAPINFO 的半主机调用崩溃,因此要在 QEMU 上运行我的代码,您必须编译 QEMU master,并使用 make run 目标来运行代码tmux 会话中的 QEMU)
不过,我想为我在与 newlib 集成时遇到的一些问题找到一些答案。
据我了解,newlib 作为一个 libc 实现,提供了一个 crt0 例程来初始化应用程序的内存区域,包括 .bss、.data、堆和堆栈。
但是,根据我的测试,GCC 链接的 crt0 不会初始化 .bss 和 .data 区域,因此会导致后面的 crt0 例程崩溃。
所以我必须为 .bss 和 .data 编写自己的初始化代码,以使其正确运行。
所以我想了解我的做法是否正确?我是否遗漏了一些可以让 newlib 为我初始化这些区域的东西?还是按照惯例自己初始化?
注意:我正在使用 arm-none-eabi-gcc stable 9-2019-q4-major
【问题讨论】:
-
您确认您链接了 newlib 启动文件并检查了 newlib crt 源,但尽管它没有链接该文件?或者当您检查 newlib 时,它没有初始化 .data 和 .bss 的引导文件? (这是链接器问题还是代码问题)?
-
gcc 不会链接链接器,如果您允许,gcc 会启动链接器,但在这种情况下,您可能希望自己控制链接器。 YMMV 如果您让 gcc 调用链接器,那么您需要确保它正在使用您想要的文件并将其放在正确的位置
-
引导代码和链接描述文件有着密切的关系,它们是一对/集合(对于那些选择过度复杂化链接描述文件的人(大多数人))
-
@old_timer 我确认链接器链接了一个 crt0 并且通过 dissaembly 它似乎是 newlib crt0 除了它没有 .bss 和 .data 初始化代码。虽然 newlib 源似乎有 init .bss 代码:github.com/bminor/newlib/blob/… 但我没有在 newlib 源中找到 .data 初始化代码。
标签: gcc arm qemu newlib semihosting