Как найти имя автора модуля linux

Ядро linuxДоброго времени, уважаемые читатели www.k-max.name!

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

Общая информация

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

Исторически, ядро Linux выпускается под определенной версией. То есть имеет определенную маркировку нумерацию. Нумерация версии ядра Linux на текущий момент содержит четыре числа, следуя недавнему изменению в долго используемой до этого политике схемы версий, основанной на трёх числах. Для иллюстрации допустим, что номер версии составлен таким образом: A.B.C[.D] (например 2.2.1, 2.4.13 или 2.6.12.3).

  • Число A обозначает версию ядра. Оно изменяется менее часто и только тогда, когда вносятся значительные изменения в код и концепцию ядра. Оно изменялось дважды в истории ядра: в 1994 (версия 1.0) и в 1996 (версия 2.0).
  • Число B обозначает старшую версию ревизии ядра. Чётные числа обозначают стабильные ревизии, то есть те, которые предназначены для промышленного использования, такие как 1.2, 2.4 или 2.6. Нечётные числа обозначают ревизии для разработчиков, такие как 1.1 или 2.5. Они предназначены для тестирования новых улучшений и драйверов до тех пор, пока они не станут достаточно стабильными для того, чтобы быть включёнными в стабильный выпуск.
  • Число C обозначает младшую версию ревизии ядра. В старой трёхчисловой схеме нумерации, оно изменялось тогда, когда в ядро включались заплатки связанные с безопасностью, исправления ошибок, новые улучшения или драйверы. С новой политикой нумерации, однако, оно изменяется только тогда, когда вносятся новые драйверы или улучшения; небольшие исправления поддерживаются числом D.
  • Число D впервые появилось после случая, когда в коде ядра версии 2.6.8 была обнаружена грубая, требующая незамедлительного исправления ошибка, связанная с NFS. Однако, было недостаточно других изменений, для того чтобы это послужило причиной для выпуска новой младшей ревизии (которой должна была стать 2.6.9). Поэтому была выпущена версия 2.6.8.1 с единственным исправлением в виде исправления для этой ошибки. С ядра 2.6.11, эта нумерация была адаптирована в качестве новой официальной политики версий. Исправления ошибок и заплатки безопасности теперь обозначаются с помощью четвёртого числа, тогда как большие изменения выполняются в изменениях младшей версии ревизии ядра (число C).

Как я уже говорил, ядро — это код низкого уровня, который взаимодействует с интерфейсами аппаратных средств и управляет системой на низшем уровне.  В настоящее время существует громаднейшее количество разновидностей аппаратного обеспечения, файловых систем и остальных компонентов, с которыми взаимодействует ядро системы. Если поддержку всех мыслимых и не мыслимых аппаратных средств включить в ядро, то размер ядра вырастет до неподъемных величин. Для того чтобы ядро не занимало большого количества оперативной памяти и при этом оставалось универсальным, придумали — модули ядра. Модули ядра позволяют при необходимости загрузить обеспечивающее поддержку программное обеспечение, такое как драйверы для аппаратных средств или файловые системы. Это позволяет запускать систему с небольшим ядром и затем подгружать модули по мере необходимости. Часто эта подгрузка происходит автоматически, например, при подключении устройств USB.

Команды для выполнения задач загрузки и удаления модулей ядра требуют полномочий суперпользователя root. Команды, выдающие информацию о модулях, обычно могут быть выполнены обычным пользователем. Однако, в случае, если они расположены в каталоге /sbin, они будут недоступны для обычного пользователя, так как этот каталог не включается в путь поиска PATH. Таким образом, если вы не root, вам, вероятно, надо будет использовать полное наименование пути.

Просмотр информации о ядре и управление параметрами ядра (команды управления)

Просмотр общей информации о ядре (версии, имени ОС, аппаратная платформа и т.п.) производится с помощью команды uname.

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

Print-server:/tmp/123# lsmod
Module                  Size  Used by
ipv6                  235396  10
loop                   12748  0
parport_pc             22500  0
parport                31084  1 parport_pc
snd_pcm                62660  0
snd_timer              17800  1 snd_pcm
snd                    45636  2 snd_pcm,snd_timer
soundcore               6368  1 snd
snd_page_alloc          7816  1 snd_pcm
psmouse                32336  0
serio_raw               4740  0
pcspkr                  2432  0
i2c_piix4               7216  0
i2c_core               19828  1 i2c_piix4
ac                      4196  0
button                  6096  0
evdev                   8000  0
ext3                  105576  5
jbd                    39476  1 ext3
mbcache                 7108  1 ext3
sd_mod                 22200  7
ide_cd_mod             27684  0
cdrom                  30176  1 ide_cd_mod
ata_generic             4676  0
ahci                   23596  6
libata                140448  2 ata_generic,ahci
scsi_mod              129548  2 sd_mod,libata
dock                    8304  1 libata
e1000                 102656  0
piix                    6568  0 [permanent]
ide_pci_generic         3908  0 [permanent]
ide_core               96168  3 ide_cd_mod,piix,ide_pci_generic
thermal                15228  0
processor              32576  1 thermal
fan                     4196  0
thermal_sys            10856  3 thermal,processor,fan

В приведенном примере видно, что в системе загружено множество модулей. Большинство из них поставляются вместе с ядром и имеют свободную лицензию. Бывают так же модули и проприетарные (например драйвера видеоадаптеров NVIDIA). Соответственно, модульный подход позволяет включать в ядро несвободные компоненты, если проприетарная лицензия позволяет это, что избавляет от необходимости получать данные модули от производителя железа.

В примере также можно видеть, что соответствующими модулями осуществляется поддержка таких устройств как видео, SATA, SCSI, дискеты и звуковые карты, а также сетевые устройства, например, IPV6, поддержка файловых систем, такой как ext3, и Remote Procedure Call (RPC) компании Sun.

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

Команда modinfo выдает информацию об одном или нескольких модулях.

kernel-server:/tmp/123$ /sbin/modinfo ipv6
filename:       /lib/modules/2.6.26-2-686/kernel/net/ipv6/ipv6.ko
alias:          net-pf-10
license:        GPL
description:    IPv6 protocol stack for Linux
author:         Cast of dozens
depends:
vermagic:       2.6.26-2-686 SMP mod_unload modversions 686

В приведенном примере видно, что команда modinfo показывает информацию о модуле ipv6, которая включает такие параметры как имя файла и путь, лицензия, описание, автор модуля и др. Параметры модуля могут различаться в зависимости от модуля.

Отдельно хотелось бы затронуть параметр filename, содержащий путь к файлу модуля и имя файла. Имя файла модуля ipv6 оканчивается на .ko, это говорит нам, что данный модуль относится к версии ядра 2.6. В более ранней версии ядра — 2.4, имена модулей оканчивались на .o). Как видно, модуль расположен в подкаталогах каталога /lib/modules/2.6.26-2-686/, в данном пути, каталог 2.6.26-2-686 соответствует версии ядра (а так же выводу команды uname -r, что активно используется в написании скриптов). Структура подкаталогов указанного каталога отражает взаимосвязь модулей ядра и назначения модулей, думаю пример ниже это наглядно покажет:

kernel-server:/tmp/123# ls -l /lib/modules/2.6.26-2-686/kernel/
итого 12
drwxr-xr-x  3 root root 1024 Окт  1 15:40 arch
drwxr-xr-x  3 root root 4096 Окт  1 18:02 crypto
drwxr-xr-x 54 root root 1024 Окт  1 15:40 drivers
drwxr-xr-x 51 root root 3072 Окт  1 18:02 fs
drwxr-xr-x  6 root root 1024 Окт  1 18:02 lib
drwxr-xr-x 37 root root 1024 Окт  1 15:40 net
drwxr-xr-x 11 root root 1024 Окт  1 18:02 sound

В примере видно, что модули ядра расположены по подкаталогам: fs, что наводит на мысль, что тут расположены модули файловой системы, sound — модули звуковых карт и так далее.

Как же нам узнать, какие модули ядра нужны, а какие можно удалить?

А все просто: если счетчик Used By равен нулю, то модуль ядра никем и ничем не используется. Соответственно, его можно удалить.

Удаление модуля ядра происходит командой  rmmod module_name.

Удаленный модуль может понадобиться в процессе работы, для загрузки модуля необходимо выполнить команду: insmod /path/to/module.ko

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

[[email protected] test]# uname -r
2.6.27-ovz-smp-alt9
[[email protected] test]# insmod /lib/modules/`uname -r`/kernel/drivers/block/floppy.ko
[[email protected] test]# rmmod floppy
[[email protected] test]# modinfo -F filename floppy
/lib/modules/2.6.27-ovz-smp-alt9/kernel/drivers/block/floppy.ko
[[email protected] test]# insmod $(modinfo -F filename floppy)
[[email protected] test]# lsmod | grep floppy
floppy                 58244  0

Существует так же и другая команда для управления модулями: modprobe. Особенность данной команды в том, что она удаляет/добавляет модули с учетом зависимостей между модулями (зависимости между модулями прописаны в файле /lib/modules/версия/modules.dep). Пример использования:

[[email protected] root]# modprobe -r vfat
vfat: Device or resource busy
[[email protected] root]# lsmod | grep fat
vfat                   13132   1
fat                    38744   1  [vfat]
[[email protected] root]# umount /windows/D
[[email protected] root]# modprobe -r vfat
[[email protected] root]# modprobe -v --show  vfat
/sbin/insmod /lib/modules/2.4.21-37.0.1.EL/kernel/fs/fat/fat.o
/sbin/insmod /lib/modules/2.4.21-37.0.1.EL/kernel/fs/vfat/vfat.o
[[email protected] root]# lsmod | grep fat
[[email protected] root]# modprobe -v  vfat
/sbin/insmod /lib/modules/2.4.21-37.0.1.EL/kernel/fs/fat/fat.o
Using /lib/modules/2.4.21-37.0.1.EL/kernel/fs/fat/fat.o
Symbol version prefix ''
/sbin/insmod /lib/modules/2.4.21-37.0.1.EL/kernel/fs/vfat/vfat.o
Using /lib/modules/2.4.21-37.0.1.EL/kernel/fs/vfat/vfat.o
[[email protected] root]# lsmod | grep fat
vfat                   13132   0  (unused)
fat                    38744   0  [vfat]

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

Так же хочу отметить, что в Linux существует конфигурационный файл /etc/modules.conf, к которому обращается и modprobe и debmod. Данный файл в большинстве своем используется для корректировки алиасов модулей. Некоторые ОС используют другие конфигурационные файлы, таки как /etc/modprobe.conf или каталог с конфигурационными файлами — /etc/modprobe.d/.

Еще отличным источником информации о действующем ядре Linux является файл конфигурации ядра, который расположен в /boot/config-2.6…. Используя команду grep можно получить достаточно информации (например, поддерживает ли ядро файловую систему cifs):

samba-server:~# grep CONFIG_SMB_FS /boot/config-2.6.32-5-686
 # CONFIG_SMB_FS is not set
 samba-server:~# grep CONFIG_CIFS /boot/config-2.6.32-5-686
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 CONFIG_CIFS_WEAK_PW_HASH=y
 CONFIG_CIFS_UPCALL=y
 CONFIG_CIFS_XATTR=y
 CONFIG_CIFS_POSIX=y
 # CONFIG_CIFS_DEBUG2 is not set
 CONFIG_CIFS_DFS_UPCALL=y
 CONFIG_CIFS_EXPERIMENTAL=y

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

С Уважением, Mc.Sim!


Теги: kernel, Linux, modules, UNIX, загрузка, команды

Команда modinfo позволяет использовать утилиту с соответствующим именем для получения информации об указанном модуле ядра Linux. Ядро Linux является монолитным, но поддерживает модули, в рамках которых содержится код для реализации ряда его функций и драйверов устройств. В процессе компиляции ядра определенный машинный код может либо включаться в состав самого ядра, либо включаться в состав модулей, которые подгружаются ядром при необходимости без перезагрузки системы. Пользователь также может получить список всех загруженных модулей с помощью команды lsmod и загрузить любой модуль с помощью команды insmod или modprobe. Сами файлы модулей обычно расположены в директории /lib/modules/. Модули поддерживают дополнительные параметры, список которых является наиболее ценной информацией, выводящейся рассматриваемой утилитой. Кроме того, утилита позволяет получить путь к файлу модуля, информацию о его лицензии, имя его автора, список требуемых для его корректной работы модулей, а также список идентификаторов совместимого с ним оборудования и другую информацию.

Базовый синтаксис команды выглядит следующим образом:

$ modinfo [параметры] имя-модуля-или-путь-к-файлу

Утилита поддерживает ряд параметров, наиболее важными из которых являются параметр -F, позволяющий указать имя интересующего поля, -k, позволяющий работать с произвольной версией ядра Linux, а также параметры -a, -d, -l, -p и -n, позволяющие вывести лишь имя автора модуля (поле author), описание его назначения (поле description), информацию о его лицензии (поле license), список его параметров (список полей parm) и имя его файла (поле file name) соответственно.

Примеры использования

Вывод информации о модуле ядра

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

$ modinfo dvb_core
filename:       /lib/modules/5.19.0-32-generic/kernel/drivers/media/dvb-core/dvb-core.ko
license:        GPL
author:         Marcus Metzler, Ralph Metzler, Holger Waechtler
description:    DVB Core Driver
srcversion:     CF8DCFB8B0F072DBB4E0EA9
depends:        mc
retpoline:      Y
intree:         Y
name:           dvb_core
vermagic:       5.19.0-32-generic SMP preempt mod_unload modversions 
sig_id:         PKCS#7
signer:         Build time autogenerated kernel key
sig_key:        03:C5:B1:04:49:5B:AB:31:68:50:F6:CB:27:16:60:B6:2F:36:0E:38
sig_hashalgo:   sha512
signature:      21:5B:AE:74:A9:F7:6F:2F:CD:03:5D:2A:51:76:01:50:AF:CE:4E:EE:
                55:73:99:DD:BB:38:B3:57:20:F7:5F:99:89:20:20:FB:67:F5:2C:9B:
                28:BF:CA:8F:55:8C:DC:65:C1:94:C9:AF:C3:5F:4E:B4:1E:89:BC:37:
                B1:80:78:3B:07:89:58:38:AC:3C:36:52:BC:9A:BB:56:11:37:FA:DD:
                10:95:48:E4:14:57:A2:AE:47:F0:97:AE:29:C8:19:6E:63:D3:97:C9:
                D1:86:EB:12:78:AE:5E:16:BC:6D:78:EF:07:E8:44:A8:C4:E1:59:8A:
                DD:CB:5C:C6:C3:0D:6E:52:C4:78:90:EB:66:F2:8E:E6:CC:18:B2:1A:
                5A:53:A2:03:91:9D:7E:2F:3B:B3:26:FA:EF:38:B3:A3:54:A8:5F:5E:
                42:28:F5:04:07:2D:F8:A9:59:49:03:66:99:6E:63:09:0B:5B:00:9D:
                15:59:47:D8:E9:DB:16:56:40:E3:38:F4:FE:A5:59:F9:F6:6C:70:88:
                A2:68:25:A2:BD:0A:41:E6:CB:63:46:78:8C:25:EB:C0:98:F8:E0:17:
                44:A9:B2:27:B1:E0:43:19:BA:F0:DC:90:E2:CE:1D:1A:99:2F:6C:F5:
                78:1F:D0:F9:5D:BD:2D:E2:95:F1:85:7B:1F:8D:2A:23:34:41:09:AA:
                AB:BD:30:08:EF:CE:79:A3:D5:D6:5B:F5:44:45:06:71:4C:28:C5:D2:
                CC:43:35:DE:46:9C:EA:CD:DA:CD:06:3E:79:D1:34:E1:2C:1F:C1:72:
                8F:A8:FE:F1:90:09:48:3D:C9:DF:12:47:F9:E4:1A:EC:C0:16:BE:95:
                6F:E9:94:8C:FD:29:3D:72:1E:F3:9C:37:99:6E:5C:5A:B8:9E:1A:27:
                FA:5F:D2:C7:9A:45:01:0F:9B:99:BF:D4:A2:D4:E4:DF:B0:BA:77:F7:
                4B:79:D1:2D:48:CE:C7:98:EC:7C:A3:53:9C:7A:67:BD:67:C7:B7:71:
                64:61:63:FF:51:4E:1D:57:D2:AF:6F:92:A4:FC:49:E3:08:E0:44:AF:
                9B:F9:08:CD:C3:C3:2D:59:35:44:3A:8A:C0:82:CA:7A:63:5F:A9:5F:
                77:72:76:3A:2E:12:61:0D:B2:64:A2:17:59:68:FE:BA:F7:5A:5C:EE:
                B7:BF:A6:21:65:65:F0:CE:B5:80:63:34:1D:6B:8B:F2:9B:9C:5E:15:
                45:C5:D4:3F:21:49:E6:8C:BF:57:DB:D0:8C:9A:F7:36:A9:C0:2F:0C:
                DA:83:FD:CC:0D:32:1F:7C:55:98:E3:44:B6:2D:D8:D4:59:4A:39:BC:
                6D:75:63:DA:3B:BC:41:9B:07:75:4F:D2
parm:           frontend_debug:Turn on/off frontend core debugging (default:off). (int)
parm:           dvb_shutdown_timeout:wait shutdown_timeout seconds after close() before suspending hardware (int)
parm:           dvb_force_auto_inversion:0: normal (default), 1: INVERSION_AUTO forced always (int)
parm:           dvb_override_tune_delay:0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt (int)
parm:           dvb_powerdown_on_sleep:0: do not power down, 1: turn LNB voltage off on sleep (default) (int)
parm:           dvb_mfe_wait_time:Wait up to mfe_wait_time seconds on open() for multi-frontend to become available (default:5 seconds) (int)
parm:           cam_debug:enable verbose debug messages (int)
parm:           dvb_demux_tscheck:enable transport stream continuity and TEI check (int)
parm:           dvb_demux_speedcheck:enable transport stream speed check (int)
parm:           dvb_demux_feed_err_pkts:when set to 0, drop packets with the TEI bit set (1 by default) (int)
parm:           debug:Turn on/off debugging (default:off). (int)
parm:           dvbdev_debug:Turn on/off device debugging (default:off). (int)

Это информация о модуле dvb_core. Из вывода видно, что модуль является драйвером для DVB-устройств, зависит от модуля mc и поддерживает такие параметры, как frontend_debug, dvb_shutdown_timeout, dvb_force_auto_inversion, dvb_override_tune_delay, dvb_powerdown_on_sleep, dvb_mfe_wait_time, cam_debug, dvb_demux_tscheck, dvb_demux_speedcheck, dvb_demux_feed_err_pkts, debug и dvbdev_debug. Типы значений этих параметров приводятся в скобках и в нашем случае это int. Вообще, значения параметров могут иметь такие типы, как byte (байт), short (короткое целочисленное значение, 2 байта), ushort (короткое беззнаковое целочисленное значение, 2 байта), int (целочисленное значение, 4 байта), uint (беззнаковое целочисленное значение, 4 байта), long (длинное целочисленное значение, 8 байт), ulong (длинное беззнаковое целочисленное значение, 8 байт), charp (массив символов, строка), bool (логическое значение) и invbool (инвертированное целочисленное значение). Если необходимо передавать несколько значений, будет использован префикс array of, например, array of charp (массив строк).

Вывод информации о модуле из произвольной версии ядра

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

$ modinfo -k 5.15.0-60-generic dvb_core
filename:       /lib/modules/5.15.0-60-generic/kernel/drivers/media/dvb-core/dvb-core.ko
license:        GPL
author:         Marcus Metzler, Ralph Metzler, Holger Waechtler
description:    DVB Core Driver
srcversion:     0695B2A0E9C2A20F55E408E
depends:        mc
retpoline:      Y
intree:         Y
name:           dvb_core
vermagic:       5.15.0-60-generic SMP mod_unload modversions
…

Очевидно, в данном случае выведена информация о модуле из состава ядра Linux версии 5.15.0-60-generic, а не 5.19.0-32-generic, как это было ранее.

Как вы знаете из статьи что такое ядро Linux, ядро является монолитным. Это значит, что весь исполняемый код сосредоточен в одном файле. Такая архитектура имеет некоторые недостатки, например, невозможность установки новых драйверов без пересборки ядра. Но разработчики нашли решение и этой проблеме, добавив систему модулей.

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

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

Модули ядра Linux собираются только под определенную версию ядра, есть способ запуска модуля независимо от версии ядра, если они совместимы с помощью dkms, но об этом мы поговорим позже.

Находятся все модули в папке /lib/modules/. Учитывая, что модули рассчитаны только для определенной версии ядра, то в этой папке создается отдельная подпапка, для каждой установленной в системе версии ядра. В этой папке находятся сами модули и дополнительные конфигурационные файлы, модули отсортированы по категориям, в зависимости от назначения например:

ls /lib/modules/5.4.0.45-generic/kernel/

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

  • lsmod — посмотреть загруженные модули
  • modinfo — информация о модуле
  • insmod — загрузить модуль
  • rmmod — удалить модуль

Работа с модулями ядра Linux выполняется, в основном, с помощью этих команд, но могут использовать и другие.

Все модули

Такая задача возникает нечасто, но если вы хотите посмотреть все установленные модули ядра Linux в системе, делается очень просто. Все модули расположены в папке /lib/modules, а поэтому очень просто вычислить их все одной командой, или даже просто зайти в папку файловым менеджером и посмотреть.

В Ubuntu команда будет выглядеть вот так:

dpkg -S *.ko | grep /lib/modules

Можно смастерить такую конструкцию с помощью find:

find /lib/modules -name *.ko

Можем искать только для текущего ядра:

find /lib/modules/$(uname -r) -name *.ko

Также, все модули записаны в конфигурационном файле /lib/modules/modules.aliases, поэтому мы можем просто посмотреть его содержимое:

modprobe -c

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

find /lib/modules -name *.ko | grep vbox

Что загружено?

Все информация о загруженных модулях хранится в файле /proc/modules, мы можем ее вывести командой:

cat /proc/modules

Но для этого дела есть более цивилизованные методы. Это утилита lsmod и modinfo. Чтобы посмотреть загруженные модули ядра linux выполните:

sudo lsmod

Удобно проверять загружен ли модуль с помощью grep:

sudo lsmod | grep vbox

А более подробную информацию о каждом модуле можно получить с помощью утилиты modinfo:

modinfo fuse

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

Запуск модулей ядра

Загрузить модуль ядра Linux можно с помощью команд modprobe или insmod. Например, загрузим модуль vboxdrv

sudo modprobe vboxdrv

Чтобы загрузить модуль ядра linux с помощью insmod необходимо передать адрес файла модуля:

sudo insmod /lib/modules/4.1.20-11-default/weak-updates/misc/vboxdrv.ko

Напоминаю, что его можно узнать с помощью команды modinfo. Запуск модуля ядра Linux предпочтительно выполнять с помощью modprobe, поскольку эта команда не только находит файл модуля в файловой системе, но и загружает все его зависимости.

Удаление модулей ядра

Здесь аналогично две команды — modprobe, позволяет удалить модуль если ей передать опцию -r, а также есть команда rmmod. Начнем с modprobe:

sudo modprobe -r vboxdrv

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

sudo rmmod vboxdrv

Если вы получили ошибку во время выгрузки модуля, например: rmmod: ERROR: Module vboxdrv is in use by: vboxnetadp vboxnetflt, значит он еще используется другими модулями, и сначала нужно выгрузить их. В данном случае это vboxnetadp и vboxnetflt. Правильно отработавшая команда не должна ничего возвращать.

rmmod vboxnetadp vboxnetflt

Блокирование загрузки модулей

Иногда, во время загрузки системы для используемых нами устройств, загружаются не те модули ядра Linux, они либо не поддерживают нужную функциональность либо конфликтуют с другими модулями. Ярким примером можно назвать загрузку драйвера b43 вместо brcmsmac для беспроводных адаптеров Broadcom. Чтобы решить эту проблему вы можете добавлять модули в черный список. Для этого достаточно добавить одну строчку в файл /etc/modprobe.d/blacklist.conf:

sudo vi /etc/modprobe.d/blacklist.conf 

blacklist b43

Этот код добавит в черный список модуль b43.

Автозагрузка модулей

Кроме чёрного списка существует отдельный каталог, в котором можно настроить автоматическую загрузку модулей при старте системы. Это /etc/modules.load.d/. Этот каталог тоже содержит конфигурационные файлы с расширением *.conf, в которых перечислены все модули, которые надо загружать при старте системы. Для добавления своего модуля можно воспользоваться файлом /etc/modules.load.d/modules.conf. Например, добавим brcmsmac:

sudo vi /etc/modules.load.d/modules.conf

brcmsmac

Установка модулей ядра Linux

Собранные для этой версии ядра модули вы можете просто скопировать в нужную папку, собственно, мы так и поступаем, когда собираем ядро из исходников. Но с проприетарными драйверами и другими внешними драйверами, не поставляемыми в комплекте с ядром дело обстоит иначе. Эти модули поддерживают несколько версий ядра, но для их установки используется специальная технология — DKMS (Dynamic Kernel Module Support). Причем модуль, установленный таким образом один раз, будет пересобираться для каждой новой версии ядра автоматически. Обычно такие модули поставляются в виде пакетов, которые устанавливаются как и все другие приложения пакетным менеджером. Ручная установка модулей с помощью dkms выходит за рамки данной статьи.

Выводы

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

Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.

Creative Commons License

Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .

Время на прочтение
7 мин

Количество просмотров 247K


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

# modinfo rt73usb

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 в повседневной работе.

Содержание

FIXME Вступление

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

Управление модулями ядра осуществляется следующими утилитами:

  • lsmod вывод всех загруженных модулей в виде таблицы.

  • modinfo вывод информации о модуле: файл модуля, краткое описание, авторы, лицензия, параметры.

  • insmod утилита для загрузки модулей ядра. Повторяет функционал modprobe название_модуля.

  • rmmod простая программа для выгрузки модулей. Повторяет функционал modprobe -r название_модуля.

  • modprobe утилита для загрузки и выгрузки модулей.

В большинстве случаев загрузка модулей осуществляется одной из следующих команд:

sudo modprobe название_модуля
sudo insmod название_модуля

При загрузке модуля ему можно указывать определенные параметры:

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

или

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

Список параметров можно узнать выполнив

modinfo название_модуля

Выгружаются модули командами

sudo rmmod название_модуля
sudo modprobe -r название_модуля

DKMS

FIXME

Файлы конфигурации

Для того чтобы определенные модули загружались/не загружались во время старта системы их можно прописать в файл /etc/modules . Каждый модуль должен быть записан в отдельной строке. Строки начинающиеся со слова blacklist запрещают загрузку модуля.

Кроме /etc/modules существует директория /etc/modprobe.d. В ней лежат отдельные конфигурационные файлы аналогичные по сути /etc/modules.

Ссылки

Понравилась статья? Поделить с друзьями:
  • Как можно найти сыщика
  • Как исправить ошибку vendor
  • Как найти деревню по спутнику
  • Как найти наибольшее целое решение уравнения
  • Как составить цели на год примеры план