我有一个在裸机目标上运行的应用程序,具有以下结构
使用标准gcc -c
,ld
序列将其编译为ELF可执行文件(system.elf)。我使用链接器生成一个地图文件,显示所有符号的地址。
现在,在不重新刷新系统的情况下,我需要使用自定义运行时加载器添加额外的功能。请记住,这是一款没有操作系统的裸机。
我想
我以为我可以重用map文件来链接extra.o对system.elf但是这不起作用:
ld -o extraExe extra.o system.map
gcc或ld是否有某种模式来制作这种延迟链接程序?如果没有,我如何实现上面概述的动态代码加载?
答案 0 :(得分:6)
您可以在ld中使用'-R filename '或'--just-symbols = filename '命令选项。它从文件名中读取符号名称及其地址,但不重新定位或将其包含在输出中。这允许输出文件以符号方式引用system.elf程序中定义的内存的绝对位置。 (参考ftp://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html)。
所以这里 filename 将是'system.elf'。您可以使用GCC编译extra.c,通常包括services.h但没有链接并生成'extra.o',然后调用ld,如下所示:
ld -R"system.elf" -o"extra.out" extra.o
'extra.out'将链接您的符号。您可以使用objdump来比较'extra.out'和'extra.o'的内容。
请注意,您始终可以将程序的起始地址传递给ld(例如-defsym _TEXT_START_ADDR = 0xAAAA0123)以及其他内存部分(如bss,data)的起始地址。 (即-Tbss,-Tdata)
小心使用与'system.elf'不冲突的有效地址,因为ld不会产生错误。您可以在原始链接描述文件中为加载的代码+ data + bss定义新区域,然后重新编译system.elf,然后在链接'extra.o'时将起始地址指向您定义的区域。