我正在开发一个裸机嵌入式应用程序;无操作系统或MMU。我使用的工具链由arm-none-eabi-gcc、ld和make组成。它需要动态加载/卸载一些插件,我不知道如何为这种配置创建脚本。
宿主应用程序有一个定义的插件系统API,它由init_plugin()和execute_plugin()的函数声明组成。
有几个C文件叫做plugin01.c, plugin02.c…,它们都实现了那个定义的API。我想编译它们,然后把所有的插件在完全相同的地址空间。一次只加载一个插件,所以不存在内存冲突的问题。编译和链接后,我会从输出文件中提取这些插件,并将它们分别加载到目标硬件中。我需要帮助解决两个问题:
- 链接器不应该抱怨同一函数的多个不同定义 链接器需要将pluginXX.c文件中的所有代码放入相同的内存范围。它应该在链接每个插件后重置位置计数器。它应该分配相同的VMA和不同的LMA。相同的VMA允许插件在加载到该位置时运行,不同的LMA允许我从输出文件中提取编译和链接的插件。
告诉大家,我已经解决了。
解决了符号名冲突的问题,在所有章节前加上。pluginxx字符串,并将符号重命名为pluginXX_init_plugin和pluginXX_execute_plugin。
使用链接器的OVERLAY特性解决了将所有插件代码放入同一地址空间的问题。所有与主机链接在一起的插件只有一个链接器通过,这保证了所有内容都被正确链接。
在此之前,我尝试了两步链接,将部分主机代码链接到目标文件中,然后将每个插件分别链接。这是浪费时间。在部分链接步骤中,未使用的代码不能被丢弃(——gc-sections选项与部分链接——relocatable选项一起不可用),并且代码将无法放入可用内存中。