Как написать динамический загрузчик для голой металлической руки-приложения - PullRequest
10 голосов
/ 11 апреля 2011

Я работаю над проектом на базе процессора arm9. Мы используем только голое железо без какой-либо операционной системы, поэтому, к сожалению, у нас пока нет поддержки общих библиотек / динамического загрузчика.

Я хотел бы иметь возможность загружать библиотеки, например, с SD-карты, которые также могут вызывать функции из основного приложения.

Моей первой попыткой было использование возможности наложения компоновщика (размещение библиотеки в определенных абсолютно позиционированных разделах), но здесь есть проблема с вызовом основных функций приложения, как я упоминал ранее -> при каждом изменении основного приложения, которое библиотеки должны выполнять перекомпилировать снова, чтобы иметь возможность перезвонить.

В соответствии с этим я должен написать свой собственный динамический загрузчик, но я новичок в этой области. Может, кто-нибудь подскажет, как с этим бороться или как начать с такого проекта? Мы используем gcc для цели эльфа.

С уважением Jan

1 Ответ

6 голосов
/ 11 апреля 2011

Отметьте это примечание к приложению .В нем подробно описывается, как работает динамическое связывание и что нужно сделать, чтобы написать собственный динамический загрузчик.Это также дает некоторые альтернативы этому.Я думаю, что таблицы переходов достаточно легко реализовать, и они решат вашу проблему с изменением адресов 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);
  //...
}

Надеюсь, это поможет!

...