Модули ядра не найдены debian

Обновлено: 03.07.2024

У меня есть модуль ядра Linux, который я скомпилировал динамически. Как это добавляется в автозагрузку? Есть много .ko файлов в /lib/modules . Как устанавливается приоритет для загрузки этих модулей?

Они не загружаются автоматически при запуске или в любое другое время, хотя многие из них в конечном итоге загружаются во время загрузки. Есть три различных механизма, с помощью которых это происходит:

Запрос в пользовательском пространстве: охватывает все, от служб init до udev и командной строки. Init или udev, вероятно, являются наиболее простым средством, если вы хотите загрузить определенный модуль во время загрузки.

Устройство с горячим подключением: когда вы подключаете что-либо, например, к USB или PCI, ядро ​​обнаруживает это и запрашивает соответствующий модуль на основе того, как устройство идентифицирует себя.

Необходимый протокол или другая реализация : когда ядру нужно что-то сделать, например, прочитать файловую систему, и обнаружить, что для этого ему не хватает знаний, оно запросит модуль.

Обратите внимание, что для последних двух я использовал фразу «запросить модуль» - это потому, что ядро ​​фактически загружается через демон userpace, kmod который выполняется /sbin/modprobe . По словам Вольфганга Моерера из Linux Kernel Architecture , в ядре 2.6 есть только

100 различных точек, где он вызывает внутреннюю request_module() функцию.

modprobe использует базу данных установленных MODULE_ALIAS. Они явно указаны в исходном коде модуля или получены из его MODULE_DEVICE_TABLE, который представляет собой список идентификаторов OEM-устройств, которые обслуживает модуль.

Многие системы настроены на использование initrd или initramfs . Это образы файловой системы, которые загружаются загрузчиком и становятся доступными ядру до его монтирования в корневой раздел. Это позволяет скомпилировать драйверы, необходимые для монтирования корневого раздела (драйверы дисков, драйверы файловой системы, драйверы устройств отображения или логических томов,…), и загрузить их из initrd / initramfs.

Скрипты запуска в initrd ( /linuxrc ) или initramfs ( /init ) обычно загружают некоторые модули и обнаруживают корневую файловую систему. Каждый дистрибутив имеет свою настройку. Ubuntu использует initramfs, который собран из компонентов в initramfs-tools пакете и регенерирован для каждого ядра на основе необходимых драйверов для монтирования корневой файловой системы.

После того, как корневая файловая система смонтирована, во время загрузки системы загружаются модули, перечисленные в /etc/modules (Debian,…) или /etc/modules.conf (Red Hat, Arch,…). Этот файл обычно содержит несколько модулей, если таковые имеются. Большинство модулей загружаются по требованию.

Когда ядро ​​обнаруживает некоторое оборудование, для которого ему не хватает драйвера, или некоторые другие компоненты, такие как сетевые протоколы или криптографические алгоритмы, оно вызывает /sbin/modprobe загрузку модуля. Для драйверов аппаратного обеспечения ядро ​​передает имена, которые кодируют идентификатор PCI, идентификатор USB или другое систематическое обозначение оборудования. Существует таблица, в /lib/modules/$VERSION/modules.alias которой эти систематические обозначения сопоставляются с именами модулей. Эта таблица генерируется depmod и читается modprobe .

Если у вас есть дополнительный модуль ядра, который вы скомпилировали вручную для аппаратного устройства, поместите его в /lib/modules/$VERSION/local (создайте local подкаталог, если он не существует) и запустите depmod -a для регенерации базы данных псевдонимов. Если модуль предназначен для какой-то необычной функции, которую ядро ​​не может обнаружить автоматически, поместите его /lib/modules/$VERSION/local , запустите depmod -a для анализа его зависимостей и добавьте имя модуля /etc/modules .

Последние версии ядра Linux имеют драйверы для новых устройств и другие нововведения. К сожалению, многие популярные дистрибутивы Linux не спешат обновить ядро. Данная инструкция покажет, как легко, без компиляции, установить любую версию ядра Linux в Debian и производные дистрибутивы, например, в Kali Linux и LMDE (Linux Mint Debian Edition). Вы можете выбрать для установки как более новое ядро, так и более старое, чем предлагает репозиторий вашего дистрибутива.

При желании, вы без проблем можете удалить установленные ядра Linux и вернуться к ядру из репозитория.

Обратите внимание, что для Ubuntu и производных дистрибутивов имеется отдельная инструкция, поскольку процесс обновления ядер различается: Как установить последние версии ядра Linux в Ubuntu и Linux Mint.

Предупреждение перед обновлением ядра

Необходимо помнить, что из-за несовместимости ядра с программами (в первую очередь, с проприетарными видео драйверами), вы можете столкнуться с проблемами, в том числе с чёрным экраном во время загрузки.

В большинстве случаев, возникшие проблемы можно решить без переустановки дистрибутива. Начните с того, что в меню загрузки перейдите в дополнительные параметры и загрузитесь с предыдущей версией ядра. Выполнив загрузку, удалите проблемное ядро.

Проблемы могут вызвать проприетарные драйверы для видеокарт, поскольку старые версии могут быть не совместимы с последними версиями ядра без патча. Если у вас установлены проприетарные видео драйверы, то серьёзной подумайте, прежде чем следовать инструкциям ниже. Также подготовьтесь, поищите инструкции, как решить проблему при загрузки дистрибутива в чёрный экран.

Следует быть особенно осторожным владельцам старых дистрибутивов — настоятельно рекомендуется обновлять ядро только на последних версиях ОС.

Ещё одна вполне вероятная проблема, с которой вы можете столкнуться если установите ядро самой последней версии — проблема с неразрешёнными зависимостями и как следствие невозможность использования менеджера пакетов apt для обновления и установки программ. Если вы столкнулись с ситуацией, когда после успешной установки нового ядра не получается обновить пакеты с помощью apt, то попробуйте устанавливать более ранние версии ядра, которые вам подходят, а версии, вызывающие проблемы с зависимостями, удаляйте. Помните, что невозможно удалить ядро с которым вы загрузились — перед удалением загрузите компьютер с любой другой версией ядра.

Обновление ядра до последней версии в Debian

Данный раздел должен подойти для всех вариаций и производных Debian, например:

  • Debian stable
  • Debian testing
  • Kali Linux
  • Linux Mint Debian Edition (LMDE)
  • MX Linux
  • и другие

Проверим текущую версию ядра:


Чтобы не компилировать ядро с нуля, воспользуемся ядрами проекта XanMod Kernel.

Для установки последней версии ядра достаточно выполнить следующие команды:

Дождитесь завершения работы и перезагрузитесь.


Ещё раз проверим версию ядра:


Если по каким-либо причинам не произошло обновление меню GRUB, то выполните команду:


Как выбрать версию ядра XanMod

Всего доступны следующие метапакеты — в квадратных скобках указана версия ядра на момент написания:

  • linux-xanmod [5.13]
  • linux-xanmod-edge [5.14]
  • linux-xanmod-lts [5.10]
  • linux-xanmod-cacule [5.14-cacule]
  • linux-xanmod-rt [5.10-rt]

Вы можете проверить версию ядра в пакете linux-xanmod следующей командой:


Как вы можете убедиться, данный метапакет имеет в зависимостях (то есть фактически установит) пакеты linux-image-5.13.19-xanmod1 и linux-headers-5.13.19-xanmod1, следовательно, версия ядра в данный момент 5.13.19.

Проверим версию ядра linux-xanmod-edge:


В настоящее время версия ядра Linux в данном пакете 5.14.6.

Репозиторий XanMod содержит не только ядра, которые можно установить с помощью метапакетов, но и много других версий, вы можете их найти командой:


При установке ядра выбранной версии, вам нужно установить соответствующие файлы заголовков, оба пакета должны иметь название вида linux-image-ВЕРСИЯ-xanmod1 и linux-headers-ВЕРСИЯ-xanmod1, причём номер ВЕРСИИ должен быть одинаковый, например:



Как удалить ядро XanMod

Если вы установили ядро с помощью метапакета linux-xanmod, то вы можете удалить данный метапакет командой:

Тем не менее, это ничего не изменит, установленные ядра останутся в системе! Для удаления самих ядер используйте команду вида:

Если вы устанавливали ядро не используя метапакет, то удалите ядро и файл заголовков указав имена пакетов с их версиями, например:

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

Если ваш компьютер загружается с чёрным экраном, зависает или что-то не работает после обновления ядра, перезагрузитесь и выберите Дополнительные параметры для вашего дистрибутива в меню GRUB:


Затем выберите предыдущую версию ядра и нажмите Enter:


Независимо от причины, вам необходимо загрузиться с предыдущей версией ядра, если вы хотите удалить последнее ядро. Это потому, что вы не можете удалить ядро, которое в настоящее время используется.

Если вы не видите меню GRUB2, нажмите и удерживайте клавишу Shift или несколько раз нажмите клавишу Esc (это может варьироваться в зависимости от загрузки BIOS или UEFI и от используемой вами версии Ubuntu/Linux Mint) при загрузке GRUB. Должно появиться меню Grub, позволяющее выбрать предыдущую версию ядра.



Ядро — это та часть операционной системы, работа которой полностью скрыта от пользователя, т. к. пользователь с ним не работает напрямую: пользователь работает с программами. Но, тем не менее, без ядра невозможна работа ни одной программы, т.е. они без ядра бесполезны. Этот механизм чем-то напоминает отношения официанта и клиента: работа хорошего официанта должна быть практически незаметна для клиента, но без официанта клиент не сможет передать заказ повару, и этот заказ не будет доставлен.
В Linux ядро монолитное, т.е. все его драйвера и подсистемы работают в своем адресном пространстве, отделенном от пользовательского. Сам термин «монолит» говорит о том, что в ядре сконцентрировано всё, и, по логике, ничего не может в него добавляться или удаляться. В случае с ядром Linux — это правда лишь отчасти: ядро Linux может работать в таком режиме, однако, в подавляющем большинстве сборок возможна модификация части кода ядра без его перекомпиляции, и даже без его выгрузки. Это достигается путем загрузки и выгрузки некоторых частей ядра, которые называются модулями. Чаще всего в процессе работы необходимо подключать модули драйверов устройств, поддержки криптографических алгоритмов, сетевых средств, и, чтобы уметь это правильно делать, нужно разбираться в строении ядра и уметь правильно работать с его модулями. Об этом и пойдет речь в этой статье.

В современных ядрах при подключении оборудования модули подключаются автоматически, а это событие обрабатывается демоном udev, который создает соответствующий файл устройства в каталоге "/dev". Все это выполняется в том случае, если соответствующий модуль корректно установлен в дерево модулей. В случае с файловыми системами ситуация та же: при попытке монтирования файловой системы ядро подгружает необходимый модуль автоматически, и выполняет монтирование.
Если необходимость в модуле не на столько очевидна, ядро его не загружает самостоятельно. Например, для поддержки функции шифрования на loop устройстве нужно вручную подгрузить модуль «cryptoloop», а для непосредственного шифрования — модуль алгоритма шифрования, например «blowfish».

Поиск необходимого модуля

Модули хранятся в каталоге "/lib/modules/<версия ядра>" в виде файлов с расширением «ko». Для получения списка всех модулей из дерева можно выполнить команду поиска всех файлов с расширением «ko» в каталоге с модулями текущего ядра:

find /lib/modules/`uname -r` -name ‘*.ko’

Полученный список даст некоторое представление о доступных модулях, их назначении и именах. Например, путь «kernel/drivers/net/wireless/rt2x00/rt73usb.ko» явно указывает на то, что этот модуль — драйвер устройства беспроводной связи на базе чипа rt73. Более детальную информацию о модуле можно получить при помощи команды modinfo:

Загрузка и выгрузка модулей

Загрузить модуль в ядро можно при помощи двух команд: «insmod» и «modprobe», отличающихся друг от друга возможностью просчета и удовлетворения зависимостей. Команда «insmod» загружает конкретный файл с расширением «ko», при этом, если модуль зависит от других модулей, еще не загруженных в ядро, команда выдаст ошибку, и не загрузит модуль. Команда «modprobe» работает только с деревом модулей, и возможна загрузка только оттуда по имени модуля, а не по имени файла. Отсюда следует область применения этих команд: при помощи «insmod» подгружается файл модуля из произвольного места файловой системы (например, пользователь скомпилировал модули и перед переносом в дерево ядра решил проверить его работоспособность), а «modprobe» — для подгрузки уже готовых модулей, включенных в дерево модулей текущей версии ядра. Например, для загрузки модуля ядра «rt73usb» из дерева ядра, включая все зависимости, и отключив аппаратное шифрование, нужно выполнить команду:

После загрузки модуля можно проверить его наличие в списке загруженных в ядро модулей при помощи команды «lsmod»:

Module Size Used by
rt73usb 17305 0
crc_itu_t 999 1 rt73usb
rt2x00usb 5749 1 rt73usb
rt2x00lib 19484 2 rt73usb,rt2x00usb

Из вывода команды ясно, что модуль подгружен, а так же в своей работе использует другие модули.
Чтобы его выгрузить, можно воспользоваться командой «rmmod» или той же командой «modprobe» с ключем "-r". В качестве параметра обоим командам нужно передать только имя модуля. Если модуль не используется, то он будет выгружен, а если используется — будет выдана ошибка, и придется выгружать все модули, которые от него зависят:

Для автоматической загрузки модулей в разных дистрибутивах предусмотрены разные механизмы. Я не буду вдаваться здесь в подробности, они для каждого дистрибутива свои, но один метод загрузки всегда действенен и удобен: при помощи стартовых скриптов. В тех же RedHat системах можно записать команды загрузки модуля прямо в "/etc/rc.d/rc.local" со всеми опциями.
Файлы конфигурация модулей находится в каталоге "/etc/modprobe.d/" и имеют расширение «conf». В этих файлах преимущественно перечисляются альтернативные имена модулей, их параметры, применяемые при их загрузке, а так же черные списки, запрещенные для загрузки. Например, чтобы вышеупомянутый модуль сразу загружался с опцией «nohwcrypt=1» нужно создать файл, в котором записать строку:

options rt73usb nohwcrypt=1

Черный список модулей хранится преимущественно в файле "/etc/modules.d/blacklist.conf" в формате «blacklist <имя модуля>». Используется эта функция для запрета загрузки глючных или конфликтных модулей.

Сборка модуля и добавление его в дерево

Иногда нужного драйвера в ядре нет, поэтому приходится его компилировать вручную. Это так же тот случай, если дополнительное ПО требует добавление своего модуля в ядро, типа vmware, virtualbox или пакет поддержки карт Nvidia. Сам процесс компиляции не отличается от процесса сборки программы, но определенные требования все же есть.
Во первых, нужен компилятор. Обычно установка «gcc» устанавливает все, что нужно для сборки модуля. Если чего-то не хватает — программа сборки об этом скажет, и нужно будет доустановить недостающие пакеты.
Во вторых, нужны заголовочные файлы ядра. Дело в том, что модули ядра всегда собираются вместе с ядром, используя его заголовочные файлы, т.к. любое отклонение и несоответствие версий модуля и загруженного ядра ведет к невозможности загрузить этот модуль в ядро.
Если система работает на базе ядра дистрибутива, то нужно установить пакеты с заголовочными файлами ядра. В большинстве дистрибутивов это пакеты «kernel-headers» и/или «kernel-devel». Для сборки модулей этого будет достаточно. Если ядро собиралось вручную, то эти пакеты не нужны: достаточно сделать символическую ссылку "/usr/src/linux", ссылающуюся на дерево сконфигурированных исходных кодов текущего ядра.
После компиляции модуля на выходе будет получен один или несколько файлов с расширением «ko». Можно попробовать их загрузить при помощи команды «insmod» и протестировать их работу.
Если модули загрузились и работают (или лень вручную подгружать зависимости), нужно их скопировать в дерево модулей текущего ядра, после чего обязательно обновить зависимости модулей командой «depmod». Она пройдется рекурсивно по дереву модулей и запишет все зависимости в файл «modules.dep», который, в последствие, будет анализироваться командой «modprobe». Теперь модули готовы к загрузке командой modprobe и могут загружаться по имени со всеми зависимостями.
Стоит отметить, что при обновлении ядра этот модуль работать не будет. Нужны будут новые заголовочные файлы и потребуется заново пересобрать модуль.

Ошибка «Invalid argument» может говорить о чем угодно, саму ошибку ядро на консоль написать не может, только при помощи функции «printk» записать в системный лог. Посмотрев логи можно уже узнать в чем ошибка:

В этом примере выведена только последняя строка с ошибкой, чтобы не загромаждать статью. Модуль может написать и несколько строк, поэтому лучше выводить полный лог, или хотя бы последние строк десять.
Ошибку уже легко найти: значение «2» неприемлемо для параметра «nohwcrypt». После исправления, модуль корректно загрузится в ядро.

Из всего сказанного можно сделать один вывод: ядро Linux играет по своим правилам и занимается серьезными вещами. Тем не менее — это всего лишь программа, оно, по сути, не сильно отличается от других обычных программ. Понимание того, что ядро не так уж страшно, как кажется, может стать первым шагом к пониманию внутреннего устройства системы и, как результат, поможет быстро и эффективно решать задачи, с которыми сталкивается любой администратор Linux в повседневной работе.

Оригинал: How to Load and Unload Kernel Modules in Linux
Автор: Aaron Kili
Дата публикации: 13 июня 2017 года
Перевод: А. Кривошей
Дата перевода: июль 2017 г.

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

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

Простой пример модуля - драйвер, который предоставляет ядру доступ к аппаратному устройству, подключенному к компьютеру.

Список всех загруженных модулей ядра в Linux

В Linux названия всех модулей заканчиваются расширением .ko, и обычно они загружаются автоматически при обнаружении оборудования во время загрузки системы. Однако системный администратор может управлять модулями с помощью специальных команд.

Для вывода списка всех загруженных модулей в Linux может использоваться команда lsmod (list modules), которая читает содержимое /proc/modules.

Как загрузить или выгрузить (удалить) модули ядра в Linux

Для загрузки модуля ядра мы можем использовать команду insmod (insert module). Здесь необходимо задать полный путь к модулю. Приведенная ниже команда загружает модуль speedstep-lib.ko.

Для выгрузки модуля ядра мы будем использовать команду rmmod (remove module). Следующая команда выгрузит модуль speedstep-lib.ko.

Управление модулями ядра с помощью команды modprobe

modprobe - это интеллектуальная команда для чтения списка, загрузки и выгрузки модулей ядра. Она производит поиск всех модулей и соответствующих файлов в директории /lib/modules/$(uname -r), но не включает в поиск альтернативные конфигурационные файлы в директории /etc/modprobe.d. Таким образом, здесь вам не нужно вводить полный путь к модулю - в этом преимущество modprobe по сравнению с ранее описанными командами.

Для загрузки модуля просто введите его имя.

Для выгрузки модуля используется флаг -r.

Замечание: в modprobe выполняется автоматическое преобразование подчеркивания, поэтому при вводе названий модулей нет никакой разницы между _ и -.

Читайте также: