在嵌入式目标上动态加载代码

时间:2017-06-19 13:48:33

标签: gcc embedded ld

我有一个在裸机目标上运行的应用程序,具有以下结构

  • 的main.c
  • service.c / .H

使用标准gcc -cld序列将其编译为ELF可执行文件(system.elf)。我使用链接器生成一个地图文件,显示所有符号的地址。

现在,在不重新刷新系统的情况下,我需要使用自定义运行时加载器添加额外的功能。请记住,这是一款没有操作系统的裸机。

我想

  • 编译extra.c,它使用service.h中定义的API(并以某种方式链接现有的service.o / system.elf)
  • 将生成的可执行文件在运行时复制到我的SDRAM 并跳转到它
  • 加载的代码应该能够按预期运行并从service.c访问导出的符号

我以为我可以重用map文件来链接extra.o对system.elf但是这不起作用:

ld -o extraExe extra.o system.map

gcc或ld是否有某种模式来制作这种延迟链接程序?如果没有,我如何实现上面概述的动态代码加载?

1 个答案:

答案 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'时将起始地址指向您定义的区域。