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 выполняется автоматическое преобразование подчеркивания, поэтому при вводе названий модулей нет никакой разницы между _ и -.

Более подробно ознакомиться с опциями можно на man-странице modprobe.

Источник

IgorKa — Информационный ресурс

Немного обо всем и все о немногом, или практический опыт системного администратора.

Декабрь 2009
Пн Вт Ср Чт Пт Сб Вс
« Ноя Янв »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

Лекция №19 — Модули Linux

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

Расположены модули в каталоге /lib/modules/версия ядра. Если у вас установлено несколько версий ядра, то, как правило, в каталоге /lib/modules/ будет находится такое же количество каталогов. Например:

/linux$ ls -1 /lib/modules/
2.6.31-14-generic
2.6.31-15-generic
2.6.31-16-generic

Модули очень тесно взаимодействуют с ядром поэтому для каждой ревизии ядра генерируется свой подкаталог с модулями. В загрузочных скриптах с помощью команды uname -r вычисляется версия ядра и модули загружаются из каталога с соответствующим названием.

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

Module Size Used by
nfs_acl 2844 0
sunrpc 191712 1 nfs_acl
qnx4 8576 0

В примере видим, что работа модуля nfs_acl зависит от модуля sunrpc.

Чтобы загрузить модуль в оперативную память (и ядро могло использовать его функции) можно использовать команду insmod. Выполняется команда от имени суперпользователя и в качестве параметра нужно указать название файла модуля с указанием полного пути к файлу:

/linux$ sudo insmod /lib/modules/2.6.31-16-generic/kernel/fs/qnx4/qnx4.ko

Загружаемый модуль отвечает за возможность взаимодействия ядра с файловой системой qnx. Проверим загружен ли модуль:

/linux$ lsmod | grep qnx
qnx4 8576 0

Чтобы выгрузить модуль из памяти предназначена команда rmmod. В качестве параметра команда rmmod принимает имя модуля в том виде в котором выдает его команда lsmod. При указании имени модуля можно пользоваться клавишей TAB для дополнения имени по первым буквам.

/linux$ sudo rmmod qnx4
igor@ubuntu:

/linux$ lsmod | grep qnx

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

/linux$ sudo rmmod sunrpc
ERROR: Module sunrpc is in use by nfs_acl

Команда insmod является очень простой командой и не совсем удобной для пользователя, поэтому чаще всего используется более продвинутая команда modprobe. Чтобы с помощью команды modprobe загрузить модуль необходимо передать ей имя модуля. Например:

/linux$ sudo modprobe qnx4
igor@ubuntu:

/linux$ lsmod | grep qnx
qnx4 8576 0

Основное преимущество команды modprobe в том, что она в отличии от insmod умеет разбирать зависимости модулей. В начале я уже говорил, что модули могут зависеть от других модулей и если вы попытаетесь командой insmod загрузить модуль который зависит от другого модуля (и он не загружен), то получите ошибку. Например:

/linux$ sudo insmod /lib/modules/2.6.31-16-generic/kernel/fs/nfs_common/nfs_acl.ko
insmod: error inserting ‘/lib/modules/2.6.31-16-generic/kernel/fs/nfs_common/nfs_acl.ko’: -1 Unknown symbol in module

Команда modprobe может воспользоваться файлом /lib/modules/версия ядра/modules.dep в котором описаны все зависимости модулей. Если открыть этот файл и найти строку для модуля nfs_acl.ko, то можно увидеть, что он зависит от модуля sunrpc.ko. Командой insmod в данном случае пришлось бы воспользоваться дважды: сначала для загрузки модуля sunrpc.ko, а затем уже для модуля nfs_acl.ko:

/linux$ sudo insmod /lib/modules/2.6.31-16-generic/kernel/net/sunrpc/sunrpc.ko
igor@ubuntu:

/linux$ sudo insmod /lib/modules/2.6.31-16-generic/kernel/fs/nfs_common/nfs_acl.ko

Команда modprobe сама разбирает зависимости и загружает необходимые модули:

/linux$ sudo modprobe nfs_acl
igor@ubuntu:

/linux$ lsmod
Module Size Used by
nfs_acl 2844 0
sunrpc 191712 1 nfs_acl

Файл /lib/modules/версия ядра/modules.dep генерируется и обновляется командой depmod. Команда depmod просматривает информацию о каждом модуле и генерирует зависимости, которые записываются в файл /lib/modules/версия ядра/modules.dep.

Еще одна полезная команда при работе с модулями это команда modinfo. modinfo — считывает информацию о модуле и выдает ее на экран:

/linux$ modinfo nfs_acl
filename: /lib/modules/2.6.31-16-generic/kernel/fs/nfs_common/nfs_acl.ko
license: GPL
srcversion: F7BFA9B63618825ED524789
depends: sunrpc
vermagic: 2.6.31-16-generic SMP mod_unload modversions 586

Среди прочей видим информацию об имени файла модуля (строка filename), и зависимостях (строка depends).

Важный момент для понимания работы моделей состоит в том, что модуль во время своей загрузки может принимать параметры, которые могут влиять на его работу. Тема эта непростая и мы не будем рассматривать ее на этой лекции, но знать об этом нужно. Какие параметры может принимать модуль можно посмотреть командой modinfo. Не все модули могут принимать параметры (например у нашего модуля nfs_acl таких параметров нет), а вот в примере ниже показан модуль которому можно передавать параметры:

/linux$ modinfo snd-bt87x
filename: /lib/modules/2.6.31-16-generic/kernel/sound/pci/snd-bt87x.ko
license: GPL
parm: index:Index value for Bt87x soundcard (array of int)
parm: id:ID string for Bt87x soundcard (array of charp)
parm: enable:Enable Bt87x soundcard (array of bool)
parm: digital_rate:Digital input rate for Bt87x soundcard (array of int)
parm: load_all:Allow to load the non-whitelisted cards (bool)

Строки начинающиеся с parm и есть описания параметров.

Источник

Работаем с модулями ядра в Linux


Ядро — это та часть операционной системы, работа которой полностью скрыта от пользователя, т. к. пользователь с ним не работает напрямую: пользователь работает с программами. Но, тем не менее, без ядра невозможна работа ни одной программы, т.е. они без ядра бесполезны. Этот механизм чем-то напоминает отношения официанта и клиента: работа хорошего официанта должна быть практически незаметна для клиента, но без официанта клиент не сможет передать заказ повару, и этот заказ не будет доставлен.
В 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:

filename: /lib/modules/2.6.38-gentoo-r1/kernel/drivers/net/wireless/rt2x00/rt73usb.ko
license: GPL
firmware: rt73.bin
description: Ralink RT73 USB Wireless LAN driver.
version: 2.3.0
author: rt2x00.serialmonkey.com
depends: rt2x00lib,rt2x00usb,crc-itu-t
vermagic: 2.6.38-gentoo-r1 SMP preempt mod_unload modversions CORE2
parm: nohwcrypt:Disable hardware encryption. (bool)

Поле «firmware» указывает на то, что этот модуль сам по себе не работает, ему нужна бинарная микропрограмма устройства в специальном файле «rt73.bin». Необходимость в файле микропрограммы появилась в связи с тем, что интерфейс взаимодействия с устройством закрыт, и эти функции возложены на файл прошивки (firmware). Взять firmware можно с сайта разработчика, установочного диска, поставляемого вместе с устройством, или где-нибудь в репозиториях дистрибутива, затем нужно его скопировать в каталог «/lib/firmware», при чем имя файла должно совпадать с тем, что указано в модуле.
Следующее поле, на которое нужно обратить внимание — это поле «depends». Здесь перечислены модули, от которых зависит данный. Логично предположить, что модули друг от друга зависят, например модуль поддержки USB накопителей зависит от модуля поддержки USB контроллера. Эти зависимости просчитываются автоматически, и будут описаны ниже.
Последнее важное поле — «param». Здесь описаны все параметры, которые может принимать модуль при загрузке, и их описания. В данном случае возможен только один: «nohwcrypt», который, судя по описанию, отключает аппаратное шифрование. В скобках указан тип значения параметра.
Более подробную информацию о модуле можно прочитать в документации к исходным кодам ядра (каталог Documentation) в дереве исходных кодов. Например, найти код нужного видеорежима драйвера «vesafb» можно в файле документации «Documentation/fb/vesafb.txt» относительно корня дерева исходных кодов.

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

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

# modprobe rt73usb nohwcrypt=0

Загрузка этого модуля командой «insmod» произойдет следующим образом:

# insmod /lib/modules/2.6.38-gentoo-r1/kernel/drivers/net/wireless/rt2x00/rt73usb.ko nohwcrypt=0

Но нужно помнить, что при использовании «insmod» все зависимости придется подгружать вручную. Поэтому эта команда постепенно вытесняется командой «modprobe».

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

# lsmod | grep rt73usb

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». В качестве параметра обоим командам нужно передать только имя модуля. Если модуль не используется, то он будет выгружен, а если используется — будет выдана ошибка, и придется выгружать все модули, которые от него зависят:

# rmmod rt2x00usb
ERROR: Module rt2x00usb is in use by rt73usb

# rmmod rt73usb
# rmmod rt2x00usb

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

Для автоматической загрузки модулей в разных дистрибутивах предусмотрены разные механизмы. Я не буду вдаваться здесь в подробности, они для каждого дистрибутива свои, но один метод загрузки всегда действенен и удобен: при помощи стартовых скриптов. В тех же 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 и могут загружаться по имени со всеми зависимостями.
Стоит отметить, что при обновлении ядра этот модуль работать не будет. Нужны будут новые заголовочные файлы и потребуется заново пересобрать модуль.

«Слушаем» что говорит ядро

При появлении малейших неполадок с модулем, нужно смотреть сообщения ядра. Они выводятся по команде «dmesg» и, в зависимости от настроек syslog, в файл «/var/log/messages». Сообщения ядра могут быть информативными или отладочными, что поможет определить проблему в процессе работы модуля, а могут сообщать об ошибке работы с модулем, например недостаточности символов и зависимостей, некорректных переданных параметрах. Например, выше рассмотренный модуль «rt73usb» требует параметр типа bool, что говорит о том, что параметр может принимать либо «0», либо «1». Если попробовать передать «2», то система выдаст ошибку:

# modprobe rt73usb nohwcrypt=2
FATAL: Error inserting rt73usb (/lib/modules/2.6.38-gentoo-r1/kernel/drivers/net/wireless/rt2x00/rt73usb.ko): Invalid argument

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

# dmesg | tail -n1
rt73usb: `2′ invalid for parameter `nohwcrypt’

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

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

Источник

Читайте также:  Adobe creative cloud cleaner tool для windows
Оцените статью