Kernel module (Русский)

From ArchWiki
Состояние перевода: На этой странице представлен перевод статьи Kernel module. Дата последней синхронизации: 12 октября 2023. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

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

Чтобы создать модуль ядра, вы можете прочитать The Linux Kernel Module Programming Guide. Модуль может быть как вкомпилирован непосредственно в ядро, так и собран в виде отдельного загружаемого файла. Чтобы иметь возможность динамически загружать или выгружать модуль, его необходимо сконфигурировать как загружаемый модуль в настройке ядра (в этом случае строка, относящаяся к модулю, должна быть отмечена буквой M).

Для автоматической пересборки модулей после установки новой версии ядра используется DKMS.

Получение информации

Модули хранятся в каталоге /usr/lib/modules/версия_ядра. Чтобы узнать текущую версию вашего ядра, используйте команду uname -r.

Примечание: Часто в названии модулей используются подчёркивания (_) или дефисы (-); однако, эти символы взаимозаменяемы как при использовании команды modprobe, так и в конфигурационных файлах в /etc/modprobe.d/.

Чтобы узнать, какие модули ядра загружены в настоящий момент:

$ lsmod

Чтобы показать информацию о модуле:

$ modinfo имя_модуля

Чтобы вывести список опций, с которыми загружен модуль, используйте systool(1) из пакета sysfsutils:

$ systool -v -m имя_модуля

Чтобы отобразить настройки для всех модулей:

$ modprobe -c | less

Чтобы отобразить настройки для отдельного модуля:

$ modprobe -c | grep имя_модуля

Чтобы узнать зависимости модуля (или его псевдонима), включая сам модуль:

$ modprobe --show-depends имя_модуля

Автоматическая загрузка модулей

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

systemd

В процессе загрузки systemd загружает модули, прописанные в файлах настроек в каталоге /etc/modules-load.d/. Названия файлов соответствуют схеме /etc/modules-load.d/program.conf. Эти файлы просто содержат список названий модулей ядра, которые необходимо загружать, разделённых переносом строки. Пустые строки и строки, в которых первым непробельным символом является # или ;, игнорируются.

/etc/modules-load.d/virtio-net.conf
# Load virtio_net.ko at boot
virtio_net

Смотрите modules-load.d(5) для дополнительной информации.

Ранняя загрузка модулей

Можно выполнять загрузку модулей в «early userspace», но для этого их нужно добавить в образ initramfs. Как именно это делается, зависит от используемого вами генератора initramfs:

Управление модулями вручную

Управление модулями ядра производится с помощью утилит, предоставляемых пакетом kmod. Вы можете использовать эти утилиты вручную.

Примечание: Если вы обновили ваше ядро, но ещё не перезагрузились, modprobe не сработает без каких либо уведомлений об ошибках и завершится с кодом 1, потому что путь /usr/lib/modules/$(uname -r)/ больше не существует. Проверьте вручную существование этого пути, если modprobe не работает, чтобы убедиться, что это ваш случай.

Загрузка модуля:

# modprobe имя_модуля

Загрузка модуля из другого места (для тех модулей, которых нет в /usr/lib/modules/$(uname -r)/):

# insmod имя_файла [параметры]

Выгрузка модуля:

# modprobe -r имя_модуля

Альтернативный вариант выгрузки модуля:

# rmmod имя_модуля

Настройка параметров модуля

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

Вручную при загрузке с помощью modprobe

Основной способ передать параметры модулю — использовать команду modprobe. Параметры указываются с помощью простых присваиваний ключ=значение:

# modprobe имя_модуля имя_параметра=значение_параметра

С помощью файлов в /etc/modprobe.d/

Файлы в каталоге /etc/modprobe.d/ можно использовать для передачи настроек модуля в udev, который через modprobe управляет загрузкой модулей во время загрузки системы. Файлы в этом каталоге могут иметь любое имя, оканчивающееся расширением .conf. Синтаксис следующий:

/etc/modprobe.d/myfilename.conf
options имя_модуля имя_параметра=значение_параметра

Для передачи нескольких параметров разделяйте их пробелами, в свою очередь параметр может принимать список значений, которые разделяются запятыми:

/etc/modprobe.d/myfilename.conf
options имя_модуля имя_параметра1=значение_параметра1 имя_параметра2=значение_параметра2а,значение_параметра2б …

Например:

/etc/modprobe.d/thinkfan.conf
# On ThinkPads, this lets the 'thinkfan' daemon control fan speed
options thinkpad_acpi fan_control=1
Примечание: Если какой-либо из затрагиваемых модулей загружается из initramfs, тогда вам придётся добавить соответствующий файл .conf в массив FILES в файле mkinitcpio.conf или использовать хук modconf для добавления файла .conf в образ initramfs (не забудьте пересобрать его после внесения изменений). Чтобы посмотреть содержимое образа initramfs, можно использовать lsinitcpio.

С помощью командной строки ядра

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

имя_модуля.имя_параметра=значение_параметра

Например:

thinkpad_acpi.fan_control=1

Просто добавьте это в загрузчике в строку с ядром, как описано в статье Параметры ядра.

Создание псевдонимов

Псевдонимы (алиасы) — это альтернативные названия для модуля. Например: alias my-mod really_long_modulename означает, что вы можете использовать modprobe my-mod вместо modprobe really_long_modulename. Вы также можете использовать звёздочки в стиле shell, то есть alias my-mod* really_long_modulename означает, что modprobe my-mod-something будет иметь такой же эффект. Создайте алиас:

/etc/modprobe.d/myalias.conf
alias mymod really_long_module_name

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

/etc/modprobe.d/modprobe.conf
# Prevent Bluetooth autoload
alias net-pf-31 off

Запрет загрузки

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

Некоторые модули загружаются как часть initramfs. Команда mkinitcpio -M напечатает все автоматически обнаруженные модули: чтобы предотвратить загрузку каких-то из этих модулей в initramfs, занесите их в чёрный список в файле .conf в каталоге /etc/modprobe.d/, и хук modconf добавит этот файл в образ initramfs при его генерации. Команда mkinitcpio -v отобразит все модули, которые необходимы некоторым хукам (например, хуку filesystems, хуку block и т. д.). Если вы не используете хук modconf, то не забудьте добавить нужный вам .conf файл в секцию FILES в /etc/mkinitcpio.conf. После того, как вы запретили загрузку модулей, пересоберите образ initramfs, а затем перезагрузитесь.

С помощью файлов в /etc/modprobe.d/

Создайте файл .conf в каталоге /etc/modprobe.d/ и добавьте строку для каждого модуля, который вы хотите запретить, используя ключевое слово blacklist. Например, если вы хотите отключить PC speaker путём запрета загрузки модуля pcspkr:

/etc/modprobe.d/nobeep.conf
# Do not load the 'pcspkr' module on boot.
blacklist pcspkr
Примечание: Команда blacklist запретит автоматическую загрузку модуля, но этот модуль всё равно может загрузиться, если от него зависит какой-то не запрещённый модуль или если он загружен вручную.

Можно изменить такое поведение. Команда install заставляет modprobe запускать вашу собственную команду вместо вставки модуля в ядро как обычно. Поэтому вы можете насильно сделать так, чтобы модуль никогда не загружался:

/etc/modprobe.d/blacklist.conf
...
install имя_модуля /bin/true
...

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

С помощью командной строки ядра

Совет: Это может очень помочь, если неправильный модуль не даёт загрузиться вашей системе.

Вы также можете запрещать модули из загрузчика.

Просто добавьте module_blacklist=модуль1,модуль2,модуль3 в вашем загрузчике в строку ядра, как описано в статье Параметры ядра.

Примечание: Когда вы запрещаете несколько модулей, обратите внимание, что они разделяются только запятой. Пробелы или что-либо ещё могут нарушить синтаксис.

Решение проблем

Модули не загружаются

В случае, если конкретный модуль не загружается и журнал загрузки (доступный с помощью journalctl -b) говорит, что модуль в чёрном списке, но в каталоге /etc/modprobe.d/ нет соответствующей записи, проверьте другой каталог /usr/lib/modprobe.d/ на наличие в нём записей чёрного списка.

Модуль не будет загружен, если строка «vermagic», содержащаяся в модуле ядра, не соответствует значению текущего запущенного ядра. Если достоверно известно, что модуль совместим с текущим запущенным ядром, проверку «vermagic» можно отключить с помощью modprobe --force-vermagic.

Важно: Игнорирование проверок версии для модуля ядра может привести к сбою ядра или к неопределённому поведению системы из-за несовместимости. Используйте --force-vermagic только с особой осторожностью.

Смотрите также