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

发布于 2024-10-31 16:08:36 字数 308 浏览 1 评论 0原文

我正在做一个基于arm9处理器的项目。我们仅使用裸机,没有任何操作系统,因此不幸的是我们还不支持共享库/动态加载器。

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

我的第一次尝试是使用链接器覆盖功能(将库放置在特定的绝对定位部分中),但是正如我之前提到的,调用主应用程序函数存在一个问题 ->主应用程序的每次更改都必须再次重新编译库才能回调。

据此,我认为我必须编写自己的动态加载器,但我是这个领域的新手。请有人给我一些如何处理它或如何开始这样的项目的例子吗?我们使用 gcc 作为 arm-elf 目标。

问候 扬

I'm working on a project based on arm9 processor. We use only bare-metal without any operating system, so unfortunately we have no support for shared libraries / dynamic loader yet.

I would like to be able to have libraries loaded for example from SD card, which can also call the functions from the main application.

My first try was to use linker overlay capability (placing the library in specific absolutely positioned sections), but here is a problem with calling main app functions as I mentioned earlier -> with each change of the main application the libraries has to be recompiled again to be able to callback.

According to this I thing I will have to write my own dynamic loader, but I'm newbie in this area. Could please someone give me any example how to deal with it or how to start with such project? We are using gcc for arm-elf target.

regards
Jan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

请查看本应用说明。它详细描述了动态链接的工作原理以及编写自己的动态加载器需要做什么。它还提供了一些替代方案。我认为跳转表非常容易实现,并且可以通过更改 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,
};

如果使用这种方法,则需要在链接器文件并确保它获得固定地址)

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

#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);
  //...
}

希望这有帮助!

Check this application note. It describes in some details how dynamic linking works and what you need to do to write your own dynamic loader. It also gives some alternatives to that. I think the jump tables one is quite easy to implement and will resolve your issue with changing API addresses.


Edit: Here's how to do a simple jump table. First, decide which functions you need exported from your main program. Then make a structure of function pointers:

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

In the main program, define an instance of this structure, fill in the pointers, and place it at some predefined address:

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

(if you use this approach, you will need to describe .jumptbl section in the linker file and make sure it gets a fixed address)

In the loaded module, get the pointer to the jumptable and use it to call the main program:

#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);
  //...
}

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文