Содержание
Файлы и директории
Файл /proc/modules
предоставляет информацию о модулях, которые установлены в ядре.
Именно его содержимое используется утилитой lsmod
для отображения данных:
# head /proc/modules autofs4 20405 3 - Live 0xf8bbd000 ipt_REJECT 1867 2 - Live 0xf8b80000 nf_conntrack_ipv4 7694 2 - Live 0xf8b77000 nf_defrag_ipv4 1039 1 nf_conntrack_ipv4, Live 0xf8b6d000 iptable_filter 2173 1 - Live 0xf8b65000 ip_tables 9567 1 iptable_filter, Live 0xf8b5c000 ip6t_REJECT 3987 2 - Live 0xf8b4e000 nf_conntrack_ipv6 6940 2 - Live 0xf8b45000 nf_defrag_ipv6 8839 1 nf_conntrack_ipv6, Live 0xf8b3a000 xt_state 1064 4 - Live 0xf8b30000
Хотя информация схожа с данными lsmod
, но тут её представлено немного больше: первым указано имя модуля, потом его размер, третья колонка – количество “пользователей” этого модуля. В четвёртой колонке, Live
, указывается состояние модуля. Состояние может так же быть Loading
или Unloading
, если в настоящий момент выполняется insmod
или rmmod
. В последней колонке указывается адрес модуля в памяти.
Файл /proc/kallsyms
содержит таблицу символов ядра (/proc/ksyms
в ядрах до 2.6). Мы рассмотрим этот файл и саму таблицу в другом посте, а символы вспомним дальше, в Зависимостях модулей.
Директория /boot
содержит необходимые данные для загрузки системы, в том числе – и само ядро:
# ls -l /boot/ total 43451 -rw-r--r--. 1 root root 109958 Jun 19 23:16 config-2.6.32-431.20.3.el6.i686 -rw-r--r--. 1 root root 109953 Nov 22 2013 config-2.6.32-431.el6.i686 drwxr-xr-x. 3 root root 1024 Jun 26 19:38 efi drwxr-xr-x. 2 root root 1024 Jun 30 14:10 grub -rw-------. 1 root root 15965151 Jun 30 14:10 initramfs-2.6.32-431.20.3.el6.i686.img -rw-------. 1 root root 15921010 Jun 26 19:47 initramfs-2.6.32-431.el6.i686.img drwx------. 2 root root 12288 Jun 26 19:28 lost+found -rw-r--r--. 1 root root 190237 Jun 19 23:17 symvers-2.6.32-431.20.3.el6.i686.gz -rw-r--r--. 1 root root 190104 Nov 22 2013 symvers-2.6.32-431.el6.i686.gz -rw-r--r--. 1 root root 1983932 Jun 19 23:16 System.map-2.6.32-431.20.3.el6.i686 -rw-r--r--. 1 root root 1982877 Nov 22 2013 System.map-2.6.32-431.el6.i686 -rwxr-xr-x. 1 root root 4006368 Jun 19 23:16 vmlinuz-2.6.32-431.20.3.el6.i686 -rwxr-xr-x. 1 root root 4002656 Nov 22 2013 vmlinuz-2.6.32-431.el6.i686
Директория /boot/grub/
– файлы загрузчика GRUB.
Файлы vmlinuz
(иногда – vmlinux
) и являются самим ядром. В примере выше имеется два файла ядра:
# ls -l /boot/ | grep vm -rwxr-xr-x. 1 root root 4006368 Jun 19 23:16 vmlinuz-2.6.32-431.20.3.el6.i686 -rwxr-xr-x. 1 root root 4002656 Nov 22 2013 vmlinuz-2.6.32-431.el6.i686
Узнать, какое из них загружено в настоящий момент можно командой uname
:
# uname -r 2.6.32-431.20.3.el6.i686
Модули ядра хранятся в директории /lib/modules/<версия ядра>/kernel/lib/
:
# ls -l /lib/modules/ total 8 drwxr-xr-x. 7 root root 4096 Jun 30 14:05 2.6.32-431.20.3.el6.i686 drwxr-xr-x. 7 root root 4096 Jun 26 19:41 2.6.32-431.el6.i686
А просмотреть их можно следующей командой:
# modprobe -l | head kernel/arch/x86/kernel/cpu/mcheck/mce-inject.ko kernel/arch/x86/kernel/cpu/cpufreq/powernow-k8.ko kernel/arch/x86/kernel/cpu/cpufreq/mperf.ko kernel/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.ko kernel/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.ko kernel/arch/x86/kernel/cpu/cpufreq/p4-clockmod.ko kernel/arch/x86/kernel/cpu/cpufreq/intel_pstate.ko kernel/arch/x86/kernel/test_nx.ko kernel/arch/x86/kernel/microcode.ko kernel/arch/x86/crypto/ablk_helper.ko
Или, что бы получить информацию о конкретном модуле:
# modprobe -l ext4 kernel/fs/ext4/ext4.ko
Либо по маске:
# modprobe -l ext* kernel/fs/ext3/ext3.ko kernel/fs/ext2/ext2.ko kernel/fs/ext4/ext4.ko
Linux Kernel Module – модули ядра Linux
Linux является монолитным ядром. Монолитное ядро предоставляет базовый интерфейс для доступа к аппаратной части, и API
для процессов в пространстве пользователя для предоставления этого доступа. В отличии от этого подхода, в системах, основанных на “микроядерном” (micro-kernel) подходе, в котором в ядре содержатся только базовые службы, тогда как службы более высокого уровня вытеснены из ядра. Основным достоинством такого подхода считается высока масштабируемость.
Хотя Linux
и является монолитным ядром – оно позволяет выполнять динамическую конфигурацию благодаря использованию системы модулей. Модули ядра представляют собой специальные объекты, которые могут быть добавлены в ядро или удалены из него в любое время. После добавления – модуль расширяет возможности ядра, добавляя новые службы.
Модули так же называются “специальными” объектами, так как только в них реализованы два интерфейса – один для инициализации модуля, при первой загрузке модуля в ядро, и второй – для “уборки”, когда модуль выгружается из ядра.
Управление модулями
Linux предоставляет полный набор утилит для управления модулями. На изображении ниже предоставлены основные утилиты, а так же зависимость их от некоторых важных системных файлов модулей:
Получение информации о модулях
lsmod
Утилита lsmod (list modules) используется для отображения загруженных в ядро модулей. В результатах отображается имя модуля, размер занятой им памяти, счётчик использования (как много других модулей используют этот модуль) и список ссылающихся на этот модуль модулей:
# lsmod Module Size Used by autofs4 20405 3 ipt_REJECT 1867 2 nf_conntrack_ipv4 7694 2 nf_defrag_ipv4 1039 1 nf_conntrack_ipv4 iptable_filter 2173 1 ip_tables 9567 1 iptable_filter ip6t_REJECT 3987 2
modinfo
Утилита modinfo предоставляет расширенную информацию об указанном модуле, например – информация про модуль powernow-k8
:
# modinfo powernow-k8 filename: /lib/modules/2.6.32-431.29.2.el6.i686/kernel/arch/x86/kernel/cpu/cpufreq/powernow-k8.ko license: GPL description: AMD Athlon 64 and Opteron processor frequency driver. author: Paul Devriendt <[email protected]> and Mark Langsdorf <[email protected]> srcversion: F5108448E2E5864C4428DD0 depends: mperf vermagic: 2.6.32-431.29.2.el6.i686 SMP mod_unload modversions 686
В строке depends
отображаются зависимости этого модуля, в данном случае – это mperf
.
Разрешение зависимостей модулей
Модули ядра Linux могут предоставлять службы (называемые “символами”, symbols) для использования другими модулями (при помощи EXPORT_SYMBOL
в коде). Если другой модуль использует этот “символ”, то этот модуль непосредственно зависит от первого модуля.
Зависимости прописываются в файле /lib/modules/<версия ядра>/modules.dep
. Создаются они с помощью утилиты depmod
.
Пример зависимостей модуля powernow-k8.ko
:
# cat /lib/modules/2.6.32-431.20.3.el6.i686/modules.dep | grep powernow-k8.ko kernel/arch/x86/kernel/cpu/cpufreq/powernow-k8.ko: kernel/arch/x86/kernel/cpu/cpufreq/mperf.ko
Как видно, информация совпадает с данными из modinfo
:
depends: mperf
Другой вариант – использование утилиты modprobe
для получения списка зависимостей:
# modprobe --show-depends powernow-k8 insmod /lib/modules/2.6.32-431.29.2.el6.i686/kernel/arch/x86/kernel/cpu/cpufreq/mperf.ko insmod /lib/modules/2.6.32-431.29.2.el6.i686/kernel/arch/x86/kernel/cpu/cpufreq/powernow-k8.ko
Что бы сгенерировать зависимости новых модулей – выполните:
# deplmod -A
Что бы выполнить проверку зависимостей, но без перезаписи файла modules.dep
– выполните:
# depmod -n
Например, для модуля ipv6:
# depmod -n -v /lib/modules/2.6.32-431.20.3.el6.i686/kernel/net/ipv6/ipv6.ko | head -n 30 kernel/net/ipv6/ipv6.ko: # pci module vendor device subvendor subdevice class class_mask driver_data # usb module match_flags idVendor idProduct bcdDevice_lo bcdDevice_hi bDeviceClass bDeviceSubClass bDeviceProtocol bInterfaceClass bInterfaceSubClass bInterfaceProtocol driver_info # ccw module match_flags cu_type cu_model dev_type dev_model # ieee1394 module match_flags vendor_id model_id specifier_id version # isapnp module cardvendor carddevice driver_data vendor function ... # module matchBits bustype vendor product version evBits keyBits relBits absBits mscBits ledBits sndBits ffBits [swBits] driver_info # of module name type compatible # serio module type extra id proto # Aliases extracted from modules themselves. alias net-pf-10 ipv6 # Aliases for symbols, used by symbol_request(). alias symbol:ip6_local_out ipv6 alias symbol:ipv6_getsockopt ipv6 alias symbol:ip6_route_me_harder ipv6 alias symbol:ip6_frag_match ipv6 alias symbol:inet6_csk_search_req ipv6
Опция -n
выведет все данные на экран, вместо записи в файл modules.dep
.
Будьте осторожны с этими данными, и делайте резервную копию файлов modules.*
.
Что бы сгенерировать зависимости для всех модулей – используйте опцию -a
, например:
# depmod -a -v | tee depmod.log ... /lib/modules/2.6.32-431.20.3.el6.i686/kernel/net/openvswitch/openvswitch.ko needs "vxlan_sock_add": /lib/modules/2.6.32-431.20.3.el6.i686/kernel/drivers/net/vxlan.ko
Как видим, depmod
указывает, что для модуля openvswitch.ko
требуется “символ” vxlan_sock_add
из модуля vxlan.ko
.
Проверим файл modules.dep
:
# cat /lib/modules/2.6.32-431.20.3.el6.i686/modules.dep | grep "openvswitch" kernel/net/openvswitch/openvswitch.ko: kernel/drivers/net/vxlan.ko
Загрузка и удаление модулей
insmod
insmod
(insert module) выполняет загрузку модуля в ядро. Для ядра 2.6 файл должен иметь расширение .ko (kernel object). Если модуль содержит символы – они могут быть проинициализирвоанны в процессе загрузки модуля. Пример ниже демонстрирует загрузку модуля с опцией инициализации:
# insmod my_module.ko my_option=1
Однако, эта утилита не рекомендуется для использования, т.к. не проверяет и не загружает зависимости модулей. Далее мы рассмотрим утилиту modprobe
, которая умеет это.
rmmod
rmmod
(remove module) применяется для удаления модуля из ядра. Модуль указывается без расширения. Если счётчки использования (см. lsmod
) больше 0 – то rmmod
не выгрузит модуль, однако можно указать опцию -w
– тогда ядро выгрузит модуль, как только счётчик станет 0 (т.е. – никакие другие модули больше не будут использовать удаляемый модуль):
# rmmod my_module
Как и в случае с insmod
– рекомендуется использование modprobe
для удаления модулей.
modprobe
Утилита modprobe
является наиболее важной утилитой в управлении модулями ядра Linux. Фактически, она является собой “обёртку” утилит insmod
и rmmod
, но выполняет все действия более качественно. Вызов insmod
просто выполняет попытку загрузки модуля и в случае, если у этого модуля есть зависимости, insmod
вернёт ошибку. modprobe
же выполняет проверку зависимостей, указанных в файле module.dep
. Если модуль-зависимость не загружен – modprobe
сначала загрузит его. Кроме того, он выполняет эту проверку рекурсивно для всех модулей, которые загружает при загрузке нужного нам модуля.
modprobe
так же принимает опцию -v
, что бы отображать больше информации:
# modprobe -v snd_intel8x0 insmod /lib/modules/2.6.32-431.20.3.el6.i686/kernel/sound/core/snd-page-alloc.ko ... insmod /lib/modules/2.6.32-431.20.3.el6.i686/kernel/sound/pci/snd-intel8x0.ko
При установке модулей, учитывайте факт, что modprobe
ищет файлы модулей по пути /lib/module/$(uname -r)
.
С помощью modprobe
так же можно удалять модули. Вместо того, что бы слепо удалять модули, как это делает rmmod
, modprobe
проверяет какие модули можно удалить вместе с этим модулем, если они являются его зависимостями и не используются другими модулями. Для удаления используется опция -r
:
# modprobe -r -v snd_intel8x0 rmmod /lib/modules/2.6.32-431.20.3.el6.i686/kernel/sound/pci/snd-intel8x0.ko ... rmmod /lib/modules/2.6.32-431.20.3.el6.i686/kernel/sound/core/snd-page-alloc.ko
У modprobe
существует много других интересных опций, например – вывод списка всех доступных модулей (-l
), или модулей, соответствующих маске:
# modprobe -l dccp kernel/net/dccp/dccp.ko
Он умеет выполнять перенаправление sterr
в syslog
, выполнять dry-run (-n)
, вместо установки или удаления и многое другое.
Почитать по теме: https://access.redhat.com