Я работаю над ядром Linux 4.9 на машине aarch64, в частности mm / memory.c и драйвером пользовательской платформы.Моя цель состоит в том, чтобы мой драйвер устройства передавал некоторую информацию аппаратному обеспечению, которое происходит из функций в memory.c .
Сначала я попробовал тот же подход, который всегда использую для связи между драйверами (платформы) устройств:
EXPORT_SYMBOL
для соответствующей функции в драйвере A - Определение символа как extern в драйвере B и доступ к
Обычно работает как чудо, но на этот раз я столкнулся со следующей ошибкой при связывании:с драйвером платформы EXPORT ing и memory.c
с использованием extern :
mm/memory.c:164:(.text+0x2a874): relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 against undefined symbol `my_func'
Однако, если я сделаю обратное, то это:
- Определить и
EXPORT_SYMBOL
указатель функции в memory.c
- Назначить указатель на функцию драйвера платформы для экспортируемого символа
... это работает!
В частности ...
Драйвер платформы:
void my_func(args){ ... };
EXPORT_SYMBOL(my_func);
memory.c:
extern void my_func(args);
... вызывает ошибку компоновщика, описанную выше.
Но ...
Драйвер платформы:
extern void (*funcptr)(args);
driver_probe() {
...
funcptr = &my_func;
....
}
memory.c:
void (*funcptr)(args) = NULL;
EXPORT_SYMBOL(funcptr);
... работает!
Быстрый поиск в Googleнамекнул, что ошибка компоновщика связана с опциями gcc PIC / PIE, но я не смог найти окончательного ответа.
Теперь работает ... но ПОЧЕМУ?: -)