【问题标题】:Porting newlib to a custom ARM setup将 newlib 移植到自定义 ARM 设置
【发布时间】:2011-01-12 03:15:04
【问题描述】:

这是我的第一篇文章,它涵盖了我大约一年来一直在努力工作的东西。

基本上它归结为以下几点:我有一个 newlib 的副本,我正在尝试在 LPC2388(NXP 的 ARM7TDMI)上工作。这是在使用 arm-elf-gcc 的 linux 机器上

我的问题是,我一直在看很多关于移植 newlib 的教程,他们都在谈论存根(如退出、打开、读/写、sbrk),我有一个漂亮的如何实现所有这些功能的好主意。但是我应该把它们放在哪里?

我有来自 sources.redhat.com/pub/newlib/newlib-1.18.0.tar.gz 的 newlib 发行版,在四处寻找后我发现“syscalls.c”(在 newlib-1.18.0/newlib/libc /sys/arm),其中包含我必须更新的所有存根,但它们都填充了看起来相当完整的代码(NOT 似乎在没有 crt0.S 的情况下工作,本身不适用于我的芯片)。

我是否应该自己清除这些函数并重新编写它们?或者我应该把它们写在别的地方。我是否应该在 newlib/libc/sys 中使用我的“架构”名称创建一个全新的文件夹并更改目标以匹配?

我也很好奇在将其作为开源项目发布后,在分发此类内容时是否有适当的礼仪。我目前有一个脚本,它可以下载 binutils、arm-elf-gcc、newlib 和 gdb 并编译它们。如果我正在修改 newlib 目录中的文件,我应该提交一个我的脚本自动应用的补丁吗?还是应该将修改后的 newlib 添加到存储库中?

感谢您阅读!接下来是我正在做的更详细的细分。


对于那些想要/需要有关我的设置的更多信息的人:

我正在构建一个基于 Uzebox 项目 (http://belogic.com/uzebox/) 的 ARM 视频游戏控制台。

我一直在做各种各样的事情,从很多不同的资源中提取,我试图弄清楚。你可以在这里阅读我的冒险开始(sparkfun 论坛,没有人回复,因为我自己想出来了):forum.sparkfun.com/viewtopic.php?f=11&t=22072

我通过阅读有关移植 newlib 的 * 问题了解了所有这些,并查看了一些不同的教程(如 wiki.osdev.org/Porting_Newlib ),但他们也因告诉我实现存根而没有提及在哪里、谁来实现,什么,何时,或如何!

【问题讨论】:

  • 酷项目!这个关于软件分发和链接到现有库的问题非常适合 Stack Overflow,但您应该查看 electronics.stackexchange.com 以获得更多涉及项目电子/固件方面的问题的答案。
  • 感谢您的提醒,因为我一直在使用 PIC、msp430 和 ATMel 微处理器,所以我实际上了解很多固件/电子产品,但我从来不需要做裸机arm before,这涉及到更多的软件开发。就这些事情而言,我已经设法弄清楚了很多,但我感到震惊的是,有多少材料只是说“去下载 Keil 软件套件,然后……”如果你这样做,这似乎是一个糟糕的解决方案重新规划开源。

标签: embedded libc arm7 newlib


【解决方案1】:

但是我应该把它们放在哪里呢?

您可以将它们放在您喜欢的位置,只要它们存在于最终链接中。您可以将它们合并到 libc 库本身中,或者您可以保留其通用性,并将系统调用作为单独的目标特定对象文件或库。

您可能需要创建自己的目标特定 crt0.s 并为您的目标组装和链接它。

由 Quantum Leaps 的 Miro Samek 撰写的关于启动和运行 GNU/ARM 开发的优秀教程可在 here 获取。这些示例基于 Atmel AT91 部件,因此您需要对您的 NXP 设备有所了解以适应启动代码。

LPC2xxx 的现成 Newlib 移植层 可用here,但文件的链接似乎已损坏。 Martin Thomas 的WinARM 项目中使用了相同的移植层。这是 GNU ARM GCC 的 Windows 端口,但其中包含的示例是特定于目标而不是特定于主机的。

您应该只需要修改 Newlib 上的移植层,因为它是目标应用程序特定的,所以您不需要(实际上可能不应该)将您的代码提交给项目。

【讨论】:

  • 我实际上从来没有打算将它提交回redhat,我的意思是我将我的项目的一部分作为开​​源发布,目的是在我真正构建项目的开始之后让其他人继续开发.该教程绝对看起来很酷,我会浏览它。我实际上已经创建了一个 crt0.S 并正确链接它(也创建了我自己的第一个链接器脚本!)我想另一个问题是我做“-nostartfiles”并明确链接我自己的crt0.o,系统调用是否有类似的东西(即忽略内置的newlib syscall.c)?
  • 如果系统调用符号已经被目标文件或库解析了之前 libc(或显式链接,如果libc是隐式 - 即没有-nostdlibs选项),链接器将不要在 libc 库中搜索它们。因此,您不必担心库中的默认实现,如果您的链接顺序正确,您的代码将覆盖它们。
【解决方案2】:

当我使用 newlib 时,这正是我所做的,吹走了 crt0.s、syscalls.c 和 libcfunc.c。我个人的偏好是基于嵌入式应用程序链接 crt0.s 和 syscalls.c 的替换(将 libcfunc 中的几个函数滚动到 syscalls.c 替换中)。

我从来没有兴趣将任何工作推回发行版,因此无法帮助您。

不过,您走在正确的道路上,crt0.S 和 syscalls.c 是您想要为您的目标定制的地方。就我个人而言,我对 C 库(和 printf)感兴趣,并且主要将所有函数中性化以返回 0 或 1 或任何使函数正常工作而不妨碍链接的方法,定期制作文件我/O 函数对 rom/ram 中的链接数据进行操作。基本上没有替换或修改 newlib 中的任何其他文件,我取得了相当大的成功,所以你走在正确的道路上。

【讨论】:

  • 感谢您的信息,我实际上并不打算将它推回发行版,我正计划发布我的项目,所以我很好奇它对其他人最有利和我一起发展。我希望最终,他们不仅仅是我认识的人,所以他们需要能够自己查找/编辑文件!这更像是一个开源礼仪/项目管理的问题,实际上并没有直接的答案。感谢您的回答!
  • 我可以想到三个选择,推回到项目本身,只将更改发布到 newlib 与您的项目,无论它在哪里,或者发布您使用的所有 newlib 与您的项目的更改。我认为答案是后两种选择之一,这取决于使用您提供的指令构建所有 newlib 以及您的项目的难度,而不是提供带有完整 make 系统的完整源包。那是假设 newlib 类似于 gpl 并且您可以通过更改重新分配。
  • 我停止使用 newlib 主要是因为我在使用具有较新 gcc 版本的交叉编译器中构建它时遇到了困难,并且最终只是没有 newlib 一起使用。您可以从 newlib 的构建说明开始,以及如何将核心文件替换为您的发行版中捆绑的说明,并根据您从用户那里得到的响应调整该解决方案。