在嵌入式目标上动态加载代码
Dynamically load code on embedded target
我有一个应用程序 运行 在裸机目标上运行并具有以下结构
- main.c
- service.c/.h
使用标准 gcc -c
、ld
序列编译为 ELF 可执行文件 (system.elf)。我使用 linker 生成一个显示所有符号地址的映射文件。
现在,在不重新刷新我的系统的情况下,我需要使用自定义 运行-time 加载器添加额外的功能。请记住,这是没有 OS 的裸机。
我愿意
- 编译 extra.c,它使用 service.h 中定义的 API(并且以某种方式 link 针对现有服务。o/system.elf)
- 在运行时间将生成的可执行文件复制到我的SDRAM 并跳转到
- 加载的代码应该能够 运行 并按预期访问从 service.c 导出的符号
我认为我可以将映射文件重新用于 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' 时将起始地址指向您定义的区域。
我有一个应用程序 运行 在裸机目标上运行并具有以下结构
- main.c
- service.c/.h
使用标准 gcc -c
、ld
序列编译为 ELF 可执行文件 (system.elf)。我使用 linker 生成一个显示所有符号地址的映射文件。
现在,在不重新刷新我的系统的情况下,我需要使用自定义 运行-time 加载器添加额外的功能。请记住,这是没有 OS 的裸机。
我愿意
- 编译 extra.c,它使用 service.h 中定义的 API(并且以某种方式 link 针对现有服务。o/system.elf)
- 在运行时间将生成的可执行文件复制到我的SDRAM 并跳转到
- 加载的代码应该能够 运行 并按预期访问从 service.c 导出的符号
我认为我可以将映射文件重新用于 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' 时将起始地址指向您定义的区域。