Как перекомпилировать только один модуль ядра?

Обычно исходники ядра хранятся в /usr/src/linux-2.6.x/. Чтобы избежать перекомпиляции всего ядра при изменении исходного кода модуля, как я могу перекомпилировать только этот модуль?


person user1056635    schedule 05.01.2012    source источник


Ответы (5)


Переключитесь в корневой каталог вашего исходного дерева и выполните следующую команду:

$ make modules SUBDIRS=drivers/the_module_directory

И установить скомпилированный модуль:

$ make modules_install SUBDIRS=drivers/the_module_directory

Примечание. Как упоминает lunakid, последняя команда может не построить модуль первой, так что будьте осторожны.

person Niklas B.    schedule 05.01.2012
comment
(Просто убедитесь, что вы запускаете это в корне дерева, в отличие от меня. ;)) - person Sz.; 12.05.2014
comment
@lunakid Хорошая мысль;) Хотя должно быть совершенно ясно, что SUBDIRS относится к CWD: P - person Niklas B.; 12.05.2014
comment
Это определенно ясно, но потом я все же обнаружил, что в конце концов сижу в каталоге драйверов wacom. :) Просто не следил за моими шагами. Кроме того, не могли бы вы добавить к своему ответу, что его также можно установить таким же образом, просто поставив make modules_install SUBDIRS=.... Это почти наверняка следующий шаг, и он может быть не сразу тривиальным (хотя это кажется так, например, после того, как я напрасно потратил несколько минут на гугление... :)). Спасибо, ура! - person Sz.; 12.05.2014
comment
@lunakid Готово. Я предполагаю, что modules_install также собирается, так что это действительно одноэтапный процесс. - person Niklas B.; 12.05.2014
comment
+1, спасибо. Что касается сборки + установки: кажется, что нет: к сожалению, он просто лажает, если это действительно то, на что он похож: УСТАНОВИТЕ драйверы/ввод/сенсорный экран/wacom_w8001.ko cp: cannot stat 'drivers/input/touchscreen/wacom_w8001.ko': Нет такого файла или каталога DEPMOD 3.4.34-x61t` (хотя DEPMOD все еще работает, поэтому я не уверен.) - person Sz.; 12.05.2014
comment
@lunakid Хорошо, спасибо за отзыв, я включил это в свой ответ. - person Niklas B.; 12.05.2014
comment
Отличная работа, жаль, что я не могу +2. :) - person Sz.; 12.05.2014
comment
Это решение не работает. Попытка сделать это с mmc_block.ko возвращает сообщение, которое говорит что-то вроде No rule to make block.o. - person Melab; 04.12.2015
comment
Как только мы сделали make_install, загружает ли он библиотеку? Я попробовал rmmod dm_raid (модуль, который я собирал), проверил, успешно ли он был удален, а затем снова вставил модуль. Тем не менее я не вижу обновленных printk, которые я поместил в свой новый инструментальный модуль. Не могли бы вы сказать, нужно ли нам делать что-то еще после make_install, чтобы изменения в драйвере отражались? - person Shehbaz Jaffer; 31.12.2015

начиная с версий ядра 3.x.x и 4.x.x процедура усложняется (но надежда есть, так что продолжайте читать):

  1. make distclean если вы не просто клонировали новый исходный код, но использовали его для сборки других модулей ранее
  2. создайте новую папку где-нибудь для исходного кода модуля (пример: extra) и скопируйте в эту новую папку только исходные файлы (из исходного кода ядра или где-то еще), относящиеся к модулю, который необходимо собрать.
  3. скопируйте файл /boot/config-`uname -r` (пример: /boot/config-4.8.0-46-generic) в файл исходной папки ядра .config и запустите make oldconfig. если модуль принадлежит к исходному коду ядра, проверьте, был ли он включен, вызвав make menuconfig, выполнив поиск модуля и при необходимости применив букву «M»
  4. Корень исходного кода ядра Makefile должен быть изменен, чтобы компоненты точной версии соответствовали текущей версии (вы можете проверить с помощью make kernelversion, если он точно соответствует uname -rone)
  5. было сильное предложение создать скрипты и раньше с make scripts
  6. make prepare и make modules_prepare должны быть выполнены до фактической сборки модуля
  7. Module.symvers необходимо скопировать из папки заголовков целевой системы, соответствующей работающей версии ядра /usr/src/linux-headers-`uname -r`/Module.symvers (пример: /usr/src/linux-headers-3.13.0-117-generic/Module. symvers) в только что созданную папку с исходными файлами модуля, подготовленную для компиляции модуля (одна дополнительная в примере).
  8. создайте новый Makefile внутри папки компиляции исходного кода модуля со следующей строкой: obj-y += <module_source_file_name>.o или, если исходный код сложный, используйте руководство из здесь
  9. только тогда самое время собрать модуль с make -C <kernel source path> M=the_module_directory (пример: make -C . M=extra/)
  10. Используйте команду modprobe --dump-modversion <module_name>.ko, чтобы проверить соответствие CRC между модулем, экспортирующим API, и соответствующими значениями в Module.symvers. в случае неудачи используйте вместо этого команду modinfo <module_name>.ko
  11. проверьте, совпадает ли содержимое файла kernel.release с заголовком текущей запущенной версии. если вы обнаружите + в конце, это означает, что вы компилировали клонированный исходный код git, и ваши экспериментальные модификации привели к тому, что система сборки скомпрометировала строку localversion, добавив + в конце.
  12. если в конце сохраненного значения kernel.release обнаружен только + и это несоответствие точному имени целевого работающего ядра,

решение будет следующим:

зафиксируйте все свои изменения, заставьте тег выпуска сместиться над вашими изменениями с помощью команды git tag -a <tag version> -f. затем перестройте свои модули с шага 8

person Oleg Kokorin    schedule 26.05.2017
comment
Если драйвер имеет свой собственный подкаталог (например, linux/drivers/net/ethernet/natsemi), необходимо ли копировать код драйвера в отдельную дополнительную папку? - person novice; 07.08.2019

Вы можете передать путь к имени модуля или каталогу модуля, чтобы сделать его параметром.

make path/to/the/module/itself.ko
make path/to/the/module/directory/
person Szilárd Pfeiffer    schedule 31.05.2013
comment
make path/to/the/module/itself.ko занимает гораздо больше времени по сравнению с make modules SUBDIRS=directory/path (3 минуты против 5 секунд). На самом деле, кажется, что просто make path/to/directory не работает, он всегда говорит, что ничего не нужно делать, но я изменил код - person Lilás; 07.06.2015

make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules_install

https://askubuntu.com/questions/515407/how-recipe-to-build-only-one-kernel-module

person rocky    schedule 21.06.2018

Если вы редактировали только код в файле drivers/net/ethernet/intel/e1000/e1000_main.c

Создайте модуль.

make scripts prepare modules_prepare
make -C . M=drivers/net/ethernet/intel/e1000

Установите модуль.

cp drivers/net/ethernet/intel/e1000/e1000.ko /lib/modules/5.1.15/kernel/drivers/net/ethernet/intel/e1000/e1000.ko
person siz    schedule 03.07.2019