如何为裸机臂应用编写动态加载程序

时间:2011-04-11 09:19:40

标签: shared-libraries arm dynamic-data relocation bare-metal

我正在开发一个基于arm9处理器的项目。我们只使用裸机而没有任何操作系统,所以很遗憾我们还不支持共享库/动态加载器。

我希望能够从SD卡中加载库,也可以从主应用程序中调用函数。

我的第一次尝试是使用链接器覆盖功能(将库放置在特定的绝对定位部分),但是如前所述调用主应用程序功能存在问题 - >每次更改主应用程序时,都必须重新编译库以便能够回调。

根据这个我的事情,我将不得不编写自己的动态加载器,但我是这个领域的新手。可以请有人给我任何一个例子如何处理它或如何开始这样的项目?我们正在使用gcc作为arm-elf target。

问候 扬

1 个答案:

答案 0 :(得分:6)

检查this application note。它详细描述了动态链接的工作原理以及编写自己的动态加载程序需要做些什么。它也提供了一些替代方案。我认为跳转表非常容易实现,并且可以通过更改API地址来解决您的问题。


编辑:以下是如何进行简单的跳转表。首先,确定您需要从主程序导出哪些功能。然后创建一个函数指针结构:

typedef struct _MyAPI
{
  int    (*init)(int flags);
  int    (*exit)(int exitcode);
  void * (*getmem)(size_t size);
  void   (*freemem)(void *ptr);
} MyAPI;

在主程序中,定义此结构的实例,填写指针,并将其放在某个预定义的地址:

#include <jumptbl.h>
int    main_init(int flags)
{
  return 0;
}
//...
MyAPI main_API __attribute__((section(".jumptbl"))) = 
{
  &main_init,
  &main_exit,
  &main_getmem,
  &main_freemem,
};

(如果您使用此方法,则需要在链接器文件中描述.jumptbl部分并确保它获得固定地址)

在加载的模块中,获取指向跳转表的指针并使用它来调用主程序:

#include <jumptbl.h>

MyAPI *pAPI = (MyAPI*)(0x1000000); // there should be a better way to do this

int main()
{
  pAPI->init(0);
  void *block = pAPI->getmem(0x30);
  //...
}

希望这有帮助!