11
votes

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

1
Normally, if a "library" calls back into a "program" it does it by calling a function pointer which has been passed in a previous call to the library. That way the library doesn't depend on the revision of the program. As for making the program depend "less" on the exact build of the library, jump tables would be simple.Chris Stratton

1 Answers

7
votes

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!