Предупреждение о создании модуля ядра, использующего экспортированные символы

У меня есть два модуля ядра (скажем, modA и modB). modA экспортирует символ с EXPORT_SYMBOL(symA), а modB использует его. У меня есть заголовок modA.h для modA:

...
extern void symA(int param);
...

и в modB.c:

#include "modA.h"
...
static int __init modB_init(void)
{
    symA(10);
}
...

Если у меня insmod modB все работает нормально, мой modB корректно слинкован в ядре и функция symA вызывается корректно. Однако, когда я собираю modB, компилятор выдает предупреждение: symA is undefined. LKM — это перемещаемый ELF, так почему же компилятор выдает это предупреждение? Как это можно убрать?


person MirkoBanchi    schedule 29.02.2012    source источник


Ответы (1)


Эта проблема (и как правильно скомпилировать в этом случае) объясняется в http://www.kernel.org/doc/Documentation/kbuild/modules.txt

Иногда внешний модуль использует экспортированные символы из другого внешнего модуля. kbuild должен иметь полную информацию обо всех символах, чтобы избежать выдачи предупреждений о неопределённых символах. Для этой ситуации существует три решения.

ПРИМЕЧАНИЕ. Рекомендуется использовать метод с файлом kbuild верхнего уровня, но в некоторых ситуациях он может оказаться нецелесообразным.

Используйте файл kbuild верхнего уровня. Если у вас есть два модуля, foo.ko и bar.ko, где foo.ko нужны символы из bar.ko, вы можете использовать общий файл kbuild верхнего уровня, чтобы оба модуля были скомпилированы в одном и том же файле. строить. Рассмотрим следующий макет каталога:

  ./foo/ <= contains foo.ko       ./bar/ <= contains bar.ko

  The top-level kbuild file would then look like:

  #./Kbuild (or ./Makefile):          obj-y := foo/ bar/

  And executing

      $ make -C $KDIR M=$PWD

  will then do the expected and compile both modules with         full

знание символов из любого модуля.

Используйте дополнительный файл Module.symvers При построении внешнего модуля создается файл Module.symvers, содержащий все экспортированные символы, которые не определены в ядре. Чтобы получить доступ к символам из bar.ko, скопируйте файл Module.symvers из компиляции bar.ko в каталог, где собран foo.ko. Во время сборки модуля kbuild будет читать файл Module.symvers в каталоге внешнего модуля, а когда сборка будет завершена, будет создан новый файл Module.symvers, содержащий сумму всех определенных символов, не являющихся частью ядра.

Используйте переменную make KBUILD_EXTRA_SYMBOLS. Если копирование Module.symvers из другого модуля нецелесообразно, вы можете назначить список файлов, разделенных пробелами, для KBUILD_EXTRA_SYMBOLS в файле сборки. Эти файлы будут загружены модпостом во время инициализации его таблиц символов.

person svenfx    schedule 29.02.2012
comment
Здорово! Я пропустил это. Спасибо Госсамер! - person MirkoBanchi; 29.02.2012