Доброго времени, уважаемые читатели 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 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 в повседневной работе.
Содержание
Вступление
Управление модулями
Управление модулями ядра осуществляется следующими утилитами:
-
lsmod
вывод всех загруженных модулей в виде таблицы. -
modinfo
вывод информации о модуле: файл модуля, краткое описание, авторы, лицензия, параметры. -
insmod
утилита для загрузки модулей ядра. Повторяет функционалmodprobe название_модуля
. -
rmmod
простая программа для выгрузки модулей. Повторяет функционалmodprobe -r название_модуля
. -
modprobe
утилита для загрузки и выгрузки модулей.
В большинстве случаев загрузка модулей осуществляется одной из следующих команд:
sudo modprobe название_модуля sudo insmod название_модуля
При загрузке модуля ему можно указывать определенные параметры:
sudo modprobe название_модуля параметр=значение
или
sudo insmod название_модуля параметр=значение
Список параметров можно узнать выполнив
modinfo название_модуля
Выгружаются модули командами
sudo rmmod название_модуля sudo modprobe -r название_модуля
DKMS
Файлы конфигурации
Для того чтобы определенные модули загружались/не загружались во время старта системы их можно прописать в файл /etc/modules . Каждый модуль должен быть записан в отдельной строке. Строки начинающиеся со слова blacklist запрещают загрузку модуля.
Кроме /etc/modules существует директория /etc/modprobe.d. В ней лежат отдельные конфигурационные файлы аналогичные по сути /etc/modules.