8

我有一个嵌入式硬件系统,其中包含基于ARMboot的引导加载程序(与 Uboot 和 PPCboot 非常相似)。

该引导加载程序通常用于从闪存加载 uClinux 映像。但是,现在我正在尝试使用这个引导加载程序来运行一个独立的 helloworld 应用程序,它不需要任何链接库。实际上,它只包含while(1){}main 函数中的代码。

我的问题是我找不到应该使用哪些 GCC 设置来构建独立的格式正确的二进制文件。

我确实使用以下构建命令:

cr16-elf-gcc -o helloworld helloworld.c -nostdlib

这会产生警告消息:
警告:找不到条目符号_start;默认为 00000004

此后,在引导加载程序中,我上传了一个生成的应用程序并在某个地址启动它:

tftpboot 0xa00000 helloworld
go 0xa00004

但它不起作用:(系统重新启动。

通常它应该只是挂起(因为while(1))。

4

4 回答 4

5

我不知道那个加载器,但我认为你应该像这样使用 objcopy 将你的可执行数据转储到原始二进制文件中。不要跳到 ELF 标题,人们:)

objcopy -O binary ./a.out o.bin

还要尝试编译与位置无关的代码并阅读 ld 和 gcc 手册。

于 2010-01-08T13:39:52.900 回答
4

链接器抱怨缺少启动代码。

您需要提供两件事:启动代码和定义目标处理器地址映射的链接器命令文件。

在您的情况下,启动代码为“bl main”,但通常启动代码将至少在分支到 main 之前初始化堆栈指针。

如果您知道将示例加载到 RAM 中,则可以直接在 main 处启动程序。您需要确定 main() 的地址用于“go”命令。

于 2010-01-08T12:52:23.563 回答
1

我每天都在 ARM non-os non-lib 上操作。这是我当前的 gcc 选项:

arm-whatever-gcc -Wall -O2 -nostdlib -nostartfiles -ffreestanding -c hello.c -o hello.o

then I use the linker to combine the C code with the vector tables and such, even if it is not an image that needs a vector table using a vector table makes it easy to put your entry point on the first instruction.

于 2010-01-08T19:22:43.497 回答
0

您至少不能静态链接标准库的任何原因?您应该有一个工作程序和标准库的好处,而无需外部依赖。

此外,您的工具链/IDE 是否区分“独立应用程序”和“Linux 应用程序”?AVR32 的 IDE 具有这种区别,能够生成在嵌入式 linux 环境中运行的程序或基本上成为操作系统的独立程序。

于 2010-01-08T14:14:09.500 回答