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

Dynamically load code on embedded target

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

使用标准 gcc -cld 序列编译为 ELF 可执行文件 (system.elf)。我使用 linker 生成一个显示所有符号地址的映射文件。

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

我愿意

我认为我可以将映射文件重新用于 link extra.o 反对 system.elf 但这没有用:

ld -o extraExe extra.o system.map

gcc 或 ld 是否有一些模式可以使这个迟到的 linking 过程?如果没有,我怎样才能实现上面概述的动态代码加载?

您可以在 ld 中使用 '-R filename' 或 '--just-symbols=filename' 命令选项。它从文件名中读取符号名称及其地址,但不会重新定位它或将其包含在输出中。这允许您的输出文件象征性地引用在您的 system.elf 程序中定义的内存的绝对位置。 (参考ftp://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html)。

所以这里 文件名 将是 '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、数据)的起始地址。 (即 -Tbss、-Tdata)
注意 使用与您的 'system.elf' 不冲突的有效地址,因为 ld 不会为此生成错误。您可以在原始链接描述文件中为加载的代码+数据+bss 定义新区域并重新编译 system.elf 然后在链接 'extra.o' 时将起始地址指向您定义的区域。