我有一个嵌入式硬件系统,其中包含一个基于ARMboot的引导加载程序(与Uboot和PPCboot非常相似)。
此引导加载程序通常用于从闪存加载uClinux映像。但是,现在我正在尝试使用此引导加载程序来运行独立的helloworld应用程序,它不需要任何链接库。实际上,它只包含主函数中的while(1){}
代码。
我的问题是我无法找出我应该使用哪些GCC设置来构建一个独立的格式正确的二进制文件。
我使用以下构建命令:
cr16-elf-gcc -o helloworld helloworld.c -nostdlib
产生警告信息:
警告:找不到条目符号_start;默认为00000004
此后,在引导加载程序中,我上传了一个生成的应用程序并在某个地址启动它:
tftpboot 0xa00000 helloworld
go 0xa00004
但它不起作用:( 系统重新启动。
通常它应该挂起(因为while(1)
)。
答案 0 :(得分:5)
我不知道那个加载器,但我认为您应该使用这样的objcopy将可执行数据转储到原始二进制文件。不要跳转到ELF标题,人们:)
objcopy -O binary ./a.out o.bin
还尝试编译与位置无关的代码并阅读ld和gcc手册。
答案 1 :(得分:4)
链接器抱怨缺少启动代码。
您需要提供两件事:启动代码和定义目标处理器地址映射的链接器命令文件。
在您的情况下,启动代码为“bl main”,但通常启动代码将至少在分支到main之前初始化堆栈指针。
如果您知道要将示例加载到RAM中,则可以直接在main启动程序。您需要确定main()的地址,以便用于“go”命令。
答案 2 :(得分:1)
我每天都在ARM非操作系统上运行。这是我目前的gcc选项:
arm-whatever-gcc -Wall -O2 -nostdlib -nostartfiles -ffreestanding -c hello.c -o hello.o
然后我使用链接器将C代码与向量表等结合起来,即使它不是需要使用向量表的向量表的图像,也可以很容易地将入口点放在第一条指令上。 / p>
答案 3 :(得分:0)
您是否有任何理由无法静态链接至少标准库?你应该有一个工作程序和标准库的好处,没有外部依赖。
另外,您的工具链/ IDE是否提供了“独立应用程序”和“Linux应用程序”之间的区别? AVR32的IDE具有这种区别,能够生成在嵌入式Linux环境中运行的程序或基本上成为操作系统的独立程序。