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

Hon*_*nza 10 arm shared-libraries dynamic-data bare-metal relocation

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

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

我的第一次尝试是使用链接器覆盖功能(将库放在特定的绝对定位部分),但是这里有一个问题,就像前面提到的那样调用主应用程序函数 - >每次更改主应用程序时都需要重新编译库能够回调.

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

尊重Jan

Igo*_*sky 6

查看此应用笔记.它详细描述了动态链接的工作原理以及编写自己的动态加载程序需要做些什么.它也提供了一些替代方案.我认为跳转表很容易实现,并将通过更改API地址解决您的问题.


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

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

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

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

(如果使用此方法,则需要在链接器文件中描述.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);
  //...
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!