Ядро Linux – это ядро операционной системы Linux. Он содержит основные компоненты для работы с оборудованием и обеспечивает связь и взаимодействие между пользователем и оборудованием. Ядро Linux – это не монолитная система, но довольно гибкая, и ядро расширено так называемыми модулями ядра.
В общем, модуль ядра – это «фрагмент кода, который может быть загружен и выгружен в ядро по запросу. Они расширяют функциональные возможности ядра без перезагрузки системы». Это приводит к очень большой гибкости во время работы.
Кроме того, «модуль ядра может быть настроен как встроенный или загружаемый. Чтобы динамически загружать или удалять модуль, он должен быть настроен как загружаемый модуль в конфигурации ядра». Это делается в исходном файле ядра /usr/src/linux/.config. Встроенные модули отмечены буквой «y», а загружаемые модули – буквой «m». В качестве примера листинг 1 демонстрирует это для модуля SCSI:
Листинг 1: Объявление использования модуля SCSI
CONFIG_SCSI=y # встроенный модуль CONFIG_SCSI=m # загружаемый модуль # CONFIG_SCSI # переменная не установлена
Мы не рекомендуем редактировать файл конфигурации напрямую, но использовать команду «make config», «make menuconfig» или «make xconfig», чтобы определить использование соответствующего модуля в ядре Linux.
В системе Linux есть несколько различных команд для работы с модулями ядра. Это включает в себя перечисление модулей, загруженных в настоящее время в ядро Linux, отображение информации о модулях, а также загрузку и выгрузку модулей ядра. Ниже мы объясним эти команды более подробно.
Для текущих ядер Linux в пакете kmod предусмотрены следующие команды. Все команды являются символическими ссылками на kmod.
Начнем с команды lsmod. lsmod сокращает «список модулей» и отображает все модули, загруженные в настоящее время в ядро Linux, аккуратно форматируя содержимое файла/proc/modules. В листинге 2 показаны выходные данные, состоящие из трех столбцов: имя модуля, размер, используемый в памяти, и другие модули ядра, которые используют этот конкретный столбец.
Листинг 2: Использование lsmod
$ lsmod Module Size Used by ctr 12927 2 ccm 17534 2 snd_hrtimer 12604 1 snd_seq 57112 1 snd_seq_device 13132 1 snd_seq ... $
Могут быть доступны модули ядра, о которых вы еще не знаете. Они хранятся в каталоге /lib/modules. С помощью find в сочетании с командой uname вы можете распечатать список этих модулей. «Uname -r» просто печатает версию текущего ядра Linux. Листинг 3 демонстрирует это для более старого ядра Linux 3.16.0-7 и показывает модули для IPv6 и IRDA.
Листинг 3: Отображение доступных модулей (выбор)
$ find /lib/modules/$(uname -r) -name '*.ko' /lib/modules/3.16.0-7-amd64/kernel/net/ipv6/ip6_vti.ko /lib/modules/3.16.0-7-amd64/kernel/net/ipv6/xfrm6_tunnel.ko /lib/modules/3.16.0-7-amd64/kernel/net/ipv6/ip6_tunnel.ko /lib/modules/3.16.0-7-amd64/kernel/net/ipv6/ip6_gre.ko /lib/modules/3.16.0-7-amd64/kernel/net/irda/irnet/irnet.ko /lib/modules/3.16.0-7-amd64/kernel/net/irda/irlan/irlan.ko /lib/modules/3.16.0-7-amd64/kernel/net/irda/irda.ko /lib/modules/3.16.0-7-amd64/kernel/net/irda/ircomm/ircomm.ko /lib/modules/3.16.0-7-amd64/kernel/net/irda/ircomm/ircomm-tty.ko ... $
Команда modinfo сообщает вам больше о запрошенном модуле ядра («информация о модуле»). В качестве параметра modinfo требуется либо полный путь к модулю, либо просто имя модуля. Листинг 4 демонстрирует это для модуля ядра IrDA, работающего со стеком протокола прямого доступа через инфракрасный порт.
Листинг 4: Отображение информации о модуле
$ /sbin/modinfo irda filename: /lib/modules/3.16.0-7-amd64/kernel/net/irda/irda.ko alias: net-pf-23 license: GPL description: The Linux IrDA Protocol Stack author: Dag Brattli <dagb@cs.uit.no> & Jean Tourrilhes <jt@hpl.hp.com> depends: crc-ccitt vermagic: 3.16.0-7-amd64 SMP mod_unload modversions $
Вывод содержит различные информационные поля, такие как полный путь к модулю ядра, его псевдоним, лицензия на программное обеспечение, описание модуля, авторов, а также внутреннее устройство ядра. Поле «depends» показывает, от каких других модулей ядра оно зависит.
Информационные поля различаются от модуля к модулю. Чтобы ограничить вывод конкретным информационным полем, modinfo принимает параметр «-F» (сокращение от «–field»), за которым следует имя поля. В листинге 5 вывод ограничен информацией о лицензии, доступной с помощью поля лицензии.
Листинг 5: Отображение только определенного поля.
$ /sbin/modinfo -F license irda GPL $
В более новых ядрах Linux доступна полезная функция безопасности. Это касается модулей ядра с криптографической подписью. Как поясняется на веб-сайте проекта ядра Linux, «это позволяет повысить безопасность ядра, запрещая загрузку неподписанных модулей или модулей, подписанных недопустимым ключом. Подпись модуля повышает безопасность, затрудняя загрузку вредоносного модуля в ядро. Проверка подписи модуля выполняется ядром, поэтому нет необходимости иметь «доверенные биты пользовательского пространства».
Каждый модуль ядра имеет определенную конфигурацию. Команда modprobe, за которой следует опция «-c» (сокращение от «–showconfig»), отображает конфигурацию модуля. В сочетании с grep этот вывод ограничен определенным символом. Листинг 6 демонстрирует это для параметров IPv6.
Листинг 6: Показать конфигурацию модуля
$ /sbin/modprobe -c | grep ipv6 alias net_pf_10_proto_0_type_6 dccp_ipv6 alias net_pf_10_proto_33_type_6 dccp_ipv6 alias nf_conntrack_10 nf_conntrack_ipv6 alias nf_nat_10 nf_nat_ipv6 alias nft_afinfo_10 nf_tables_ipv6 alias nft_chain_10_nat nft_chain_nat_ipv6 alias nft_chain_10_route nft_chain_route_ipv6 alias nft_expr_10_reject nft_reject_ipv6 alias symbol:nf_defrag_ipv6_enable nf_defrag_ipv6 alias symbol:nf_nat_icmpv6_reply_translation nf_nat_ipv6 alias symbol:nft_af_ipv6 nf_tables_ipv6 alias symbol:nft_reject_ipv6_eval nft_reject_ipv6 $
Ядро Linux спроектировано как модульное, а функциональность распределена по ряду модулей. Это приводит к нескольким зависимостям модулей, которые можно снова отобразить с помощью modprobe. В листинге 7 используется опция «–show-depends», чтобы вывести список зависимостей для модуля i915.
Листинг 7: Показать зависимости модуля
$ /sbin/modprobe --show-depends i915 insmod /lib/modules/3.16.0-7-amd64/kernel/drivers/i2c/i2c-core.ko insmod /lib/modules/3.16.0-7-amd64/kernel/drivers/i2c/algos/i2c-algo-bit.ko insmod /lib/modules/3.16.0-7-amd64/kernel/drivers/thermal/thermal_sys.ko insmod /lib/modules/3.16.0-7-amd64/kernel/drivers/gpu/drm/drm.ko insmod /lib/modules/3.16.0-7-amd64/kernel/drivers/gpu/drm/drm_kms_helper.ko insmod /lib/modules/3.16.0-7-amd64/kernel/drivers/acpi/video.ko insmod /lib/modules/3.16.0-7-amd64/kernel/drivers/acpi/button.ko insmod /lib/modules/3.16.0-7-amd64/kernel/drivers/gpu/drm/i915/i915.ko $
Чтобы отобразить зависимости в виде дерева, подобного командам «tree» или «lsblk», может помочь проект modtree. Хотя он находится в свободном доступе на GitHub, он требует некоторых изменений, чтобы соответствовать правилам для бесплатного программного обеспечения и стать частью дистрибутива Linux в виде пакета.
Загрузить модуль в работающее ядро можно двумя командами – insmod («insert module») и modprobe. Имейте в виду, что между этими двумя есть небольшое, но важное различие: insmod не разрешает зависимости модулей, но modprobe умнее и делает это.
В листинге 8 показано, как вставить модуль ядра IrDA. Обратите внимание, что insmode работает с полным путем к модулю, тогда как modprobe доволен именем модуля и сам ищет его в дереве модулей для текущего ядра Linux.
Листинг 8: Вставка модуля ядра
# insmod /lib/modules/3.16.0-7-amd64/kernel/net/irda/irda.ko ... # modprobe irda
Последний шаг касается выгрузки модулей из работающего ядра. Опять же, для этой задачи доступны две команды – modprobe и rmmod («remove module»). Обе команды ожидают имя модуля в качестве параметра. В листинге 9 показано, как удалить модуль IrDA из работающего ядра Linux.
Листинг 9: Удаление модуля ядра
# rmmod irda ... # modprobe -r irda ...
Работа с модулями ядра Linux – не большая магия. Достаточно выучить несколько команд, и вы – хозяин на кухне.