"нет версии символа для module_layout" при попытке загрузить usbhid.ko
Я пытаюсь построить свой собственный модуль для usbhid.ko
, но после компиляции я не могу загрузить модуль. dmesg
говорит no symbol version for module_layout
, Мне интересно, в чем проблема? Я уже использовал исходный код ядра, предоставленный Ubuntu, и я также убедился, что версия ядра совпадает.
3 ответа
В частности, проблема в том, что при сборке модуля в исходном дереве ядра, вероятно, отсутствовал файл Modules.symvers. Система kbuild фактически предупреждает вас об этом, когда вы собираете свой модуль. Если Modules.symvers отсутствует, вы увидите:
Предупреждение: отсутствует дамп версии символов /usr/src/linux-2.6.34-12/Modules.symvers; Модули не будут иметь зависимостей и модификаций.
Если ваше ядро имеет CONFIG_MODVERSIONS
если он включен, то на этапе построения драйвера modpost он запускает scripts / mod / modpost с параметром -m. Если вы смелы и посмотрите на источник scripts / mod / modpost.c, вы увидите, что опция -m добавляет символ _module_layout_ из vmlinux, однако, если у вас нет Modules.symvers из вашего ядра, вы не получите значение CRC для этого символа, и в результате вы получите это сообщение об ошибке.
Таким образом, есть два способа обойти это.
1) Запустите полную сборку вашего работающего ядра, чтобы сгенерировать Modules.symvers, затем пересоберите ваш модуль. [Http://www.mjmwired.net/kernel/Documentation/kbuild/modules.txt][1]
51 === 2. How to Build External Modules
52
53 To build external modules, you must have a prebuilt kernel available
54 that contains the configuration and header files used in the build.
55 Also, the kernel must have been built with modules enabled. If you are
56 using a distribution kernel, there will be a package for the kernel you
57 are running provided by your distribution.
58
59 An alternative is to use the "make" target "modules_prepare." This will
60 make sure the kernel contains the information required. The target
61 exists solely as a simple way to prepare a kernel source tree for
62 building external modules.
63
64 NOTE: "modules_prepare" will not build Module.symvers even if
65 CONFIG_MODVERSIONS is set; therefore, a full kernel build needs to be
66 executed to make module versioning work.
2) Другой вариант - сказать глупому modprobe просто игнорировать все это дерьмо и просто загрузить ваш модуль в любом случае:
modprobe -f <module>
Я склоняюсь к варианту 2:)
Есть оба linux-headers
а также linux-source
установлены пакеты, соответствующие вашему ядру. Например для ядра 3.2.0-27-generic-pae
тебе нужно:
linux-headers-3.2.0-27-generic-pae
а такжеlinux-source-3.2.0-27-generic-pae
,
Если версия для указанных выше пакетов не соответствует используемой версии ядра, вам необходимо заменить $(uname -r)
со строкой версии из вашего установленного пакета ядра сверху.
Для приведенного выше примера версия пакета 3.2.0-27-generic-pae
, Когда ты бежишь uname -r
и его вывод что-то другое, то 3.2.0-27-generic-pae
тогда вам нужно заменить каждый $(uname -r)
ниже, чтобы соответствовать строке версии из установленных пакетов.
cd /usr/src/linux-source-$Version
и распакуйте архив.tar.bz2 на место и перейдите в извлеченный каталог - думаю, вы уже сделали этоcp /boot/config-$(uname -r) .config
в исходный каталог ядраcp /usr/src/linux-headers-$(uname -r)/Module.symvers .
в исходный каталог ядра
После того, как вы это сделаете, в исходном каталоге ядра сделайте следующее:
make prepare
make scripts
make M=drivers/usb/serial
- изменить путь послеM=
удовлетворить ваши потребности
К сожалению, я не знаю, как создать конкретный модуль, сохраняя при этом Module.symvers
нетронутым. дела make drivers/usb/serial/option.ko
, например, убивает Module.symvers
файл, и вы в конечном итоге с вашей первоначальной проблемой. С использованием M=
Параметр не убивает его, но вы должны собрать все модули по указанному пути - и я пока не нашел способ обойти это.
Вы должны использовать точно идентичную конфигурацию ядра перед запуском make prepare
, Кроме того, если вы собираете его вне дерева, вам нужно строить его из точно идентичных заголовков ядра, соответствующих вашему текущему работающему ядру (или целевому, если вы не запускаете его во время компиляции).