“Відсутність версії символу для модуля_лаут” при спробі завантажити usbhid.ko


27

Я намагаюся створити власний модуль для usbhid.ko, але після того, як я компілював, я не можу завантажити модуль. dmesgкаже no symbol version for module_layout. Мені цікаво, в чому проблема? Я вже використовував джерело ядра, надане Ubuntu, і я також переконався, що версія ядра однакова.

Відповіді:


22

Зокрема, проблема полягає в тому, що при створенні модуля у дереві джерела ядра, ймовірно, відсутній файл Modules.symvers. Система kbuild насправді попереджає вас про це під час створення модуля. Якщо Modules.symvers відсутній, ви побачите:

Попередження: відсутня версія dump /usr/src/linux-2.6.34-12/Modules.symvers; модулі не матимуть залежностей і модифікацій.

Якщо ваше ядро CONFIG_MODVERSIONSувімкнено, то під час фази модпості побудови драйвера він запускатиме скрипти / mod / modpost з опцією -m. Якщо ви хоробрі і погляньте на джерело script / 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 :)


1
+1 для коментаря "скажіть дурному modprobe, щоб просто ігнорувати все це лайно і просто все-таки завантажувати модуль".
Hayri Uğur Koltuk

Я спробував 2 і виявив, що модуль не завантажується автоматично під час завантаження. чи є спосіб -f під час завантаження?
Джастін Чжан

17

Встановіть linux-headersі linux-sourceпакети, і відповідні вашому ядру. Наприклад, для ядра 3.2.0-27-generic-paeвам потрібно:

  1. linux-headers-3.2.0-27-generic-pae і
  2. 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)нижче, щоб відповідати рядку версії з встановлених пакетів.

  1. cd /usr/src/linux-source-$Version і розпакуйте .tar.bz2 архів на місці і введіть CD у витягнутий каталог - я думаю, ви це вже робили
  2. cp /boot/config-$(uname -r) .config у вихідний каталог ядра
  3. cp /usr/src/linux-headers-$(uname -r)/Module.symvers . у вихідний каталог ядра

Після цього в каталозі джерела ядра зробіть це:

  1. make prepare
  2. make scripts
  3. make M=drivers/usb/serial- змінити шлях M=відповідно до ваших потреб

На жаль, я не знаю, як створити конкретний модуль, зберігаючи Module.symversнедоторканість. Робити make drivers/usb/serial/option.ko, наприклад, вбиває Module.symversфайл, і ви в кінцевому підсумку з вашої вихідної задачі. Використання M=параметра не вбиває його, але ви повинні зібрати всі модулі у вказаному шляху - і я ще не знайшов способу його обходу.


Це здається найкращим способом зробити справи, якщо ви збираєте модуль у тій же версії дерева ...
Treviño

2

Перед запуском потрібно використовувати точно ідентичну конфігурацію ядра make prepare. Крім того, якщо ви будуєте його поза деревом, вам потрібно побудувати його з точно однаковими заголовками ядра, що відповідають вашому поточному ядру (або цільовому, якщо ви не запустите його під час компіляції).


"make mrproper", "cp / boot / config - $ (uname -r) .config", "make oldconfig", "make priprema", "make script" Я використовував ці інструкції для підготовки компіляції. Мені хотілося б знати, чи скопіював я правильний файл конфігурації? здається, що існує лише одна конфігурація, яка відповідає моїй версії ядра в / boot /. Вибачте за форматування, оскільки поле для коментарів не має формату ....
SpecC

Так, це здається правильним. Куди ви посилаєтеся на збірку, а якщо не з каталогу топлевель, яке значення SUBDIRS ви передаєте?
Даніель Т Чен

Дякую за відповідь. коли я спробував побудувати usbhid.ko. Я використав цю команду "make module SUBDIRS = driver / hid / usbhid"
SpecC

коли я запустив команду "make module SUBDIRS = Drivers / hid / usbhid", я отримую таке попередження "ПОПЕРЕДЖЕННЯ: Версія символу dump /usr/src/linux-source-2.6.31/Module.symvers відсутня; модулі матимуть немає залежностей і модифікацій ".
SpecC

@SpecC Досліджуючи свою проблему, оновіть своє первісне запитання, виконуючи кроки. Потім Дан оновить свою відповідь, і ви будете постійно оновлювати, поки ви не з'ясуєте це замість рядка коментарів, які в кінцевому підсумку поховані, див. Посібник для отримання додаткових порад: meta.askubuntu.com/questions/257/how-does-ask -ubuntu-робота
Хорхе Кастро
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.