Ядро Linux монолитное, но не статичное: драйверы, файловые системы и сетевые протоколы подгружаются как модули по требованию. Задача администратора - понимать, что сейчас в ядре, уметь загрузить нужный модуль с правильными параметрами, запретить вредный автозагруз, и при этом не дёргать ядро вручную там, где это сделает udev и systemd. В этом уроке разберём весь конвейер: от modules.dep до правил udev и тюнинга через sysctl. Это типовая работа при поднятии нового железа, отладке драйвера и хардненинге сервера.

Как это работает
Модуль ядра - это файл .ko (kernel object) в дереве /lib/modules/$(uname -r)/. В 2026 на свежих системах (Debian 13, Ubuntu 24.04, RHEL 10, Fedora 41+) они сжаты zstd и лежат как .ko.zst; kmod распаковывает их на лету, так что для вас это прозрачно.
Все привычные команды - lsmod, modprobe, insmod, rmmod, modinfo, depmod - это один бинарь kmod, доступный под разными именами через симлинки. Поэтому поведение у них согласованное.
Ключевой момент - зависимости. Драйвер часто опирается на другие модули (например, сетевая карта тянет общий слой). Карту этих связей строит depmod: он сканирует символы во всех .ko и пишет файл /lib/modules/$(uname -r)/modules.dep плюс хэши и алиасы рядом. Именно поэтому modprobe умный, а insmod - нет: modprobe читает modules.dep и грузит всю цепочку зависимостей в правильном порядке, а insmod пихает один файл по точному пути и падает, если зависимости не загружены. На практике insmod/rmmod почти не нужны - это инструмент для отладки одиночного .ko.
Автоматику обеспечивает udev. Когда железо появляется, ядро шлёт uevent; udev по таблице модальясов (modules.alias, тоже от depmod) находит подходящий драйвер и вызывает modprobe. Поэтому большинство модулей вы вообще не грузите руками - они приезжают сами.
Конфигурация раздельная по смыслу. Каталог /etc/modprobe.d управляет КАК грузить: задаёт options (параметры модуля), blacklist (не грузить по этому имени-алиасу), install/alias (подменить действие). Каталог /etc/modules-load.d говорит ЧТО грузить принудительно при старте - его читает systemd-modules-load.service, даже если железа как бы и нет (нужно для nf_conntrack, br_netfilter и т.п.).
Параметры самого ядра (не модулей) - это sysctl: интерфейс к /proc/sys. На лету меняете через sysctl, постоянно - файлами в /etc/sysctl.d. Это сеть, виртуальная память, лимиты - то, что не требует перезагрузки.
Команды и примеры
Посмотреть загруженное и узнать про модуль:
Код: Выделить всё
lsmod # имя, размер, счётчик использований, кто зависит
modinfo nf_conntrack # путь, лицензия, зависимости, параметры (parm:)
modinfo -p i915 # только параметры с описанием
Код: Выделить всё
modprobe nf_conntrack
modprobe i915 enable_psr=0 # параметр на эту загрузку
modprobe -r nf_conntrack # выгрузить (с зависимостями, если не заняты)
modprobe -n -v r8169 # сухой прогон: что бы сделалось
Код: Выделить всё
insmod /lib/modules/$(uname -r)/kernel/drivers/net/dummy.ko.zst
rmmod dummy
Код: Выделить всё
depmod -a # для текущего ядра
depmod 6.12.0-amd64 # для конкретной версии
Код: Выделить всё
echo 'options i915 enable_psr=0' > /etc/modprobe.d/i915.conf
echo 'blacklist nouveau' > /etc/modprobe.d/nvidia.conf
echo 'install nouveau /bin/false' >> /etc/modprobe.d/nvidia.conf
Код: Выделить всё
echo 'br_netfilter' > /etc/modules-load.d/k8s.conf
systemctl restart systemd-modules-load.service
systemctl status systemd-modules-load.service
Правило udev (например, фиксированное имя для USB-устройства):
Код: Выделить всё
# /etc/udev/rules.d/70-mydev.rules
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", SYMLINK+="ttyMODBUS"
udevadm control --reload
udevadm trigger
udevadm info -a /dev/ttyUSB0 # какие атрибуты можно матчить
Код: Выделить всё
sysctl net.ipv4.ip_forward # прочитать
sysctl -w net.ipv4.ip_forward=1 # на лету (до перезагрузки)
echo 'net.ipv4.ip_forward = 1' > /etc/sysctl.d/99-router.conf
sysctl --system # применить все .d
Частые грабли
- Поставили .ko вручную и сделали modprobe - ловите FATAL Module not found. Забыли depmod -a: карта зависимостей не знает о новом модуле.
- blacklist не мешает прямой загрузке. blacklist отключает только автозагруз по алиасу; modprobe nouveau руками всё равно сработает. Чтобы наглухо - строка install <модуль> /bin/false.
- Поместили blacklist в /etc/modules-load.d - там это бессмысленно: файл задаёт ЧТО грузить, а синтаксис options/blacklist понимает только modprobe.d.
- Драйвер вшит в initramfs (графика, диск). Правка modprobe.d не подействует, пока не пересоберёте образ: update-initramfs -u (Debian/Ubuntu) или dracut -f (RHEL/Fedora).
- sysctl -w забывается после ребута. Постоянное значение - только файлом в /etc/sysctl.d, иначе откатится.
- Меняли .rules и удивляетесь тишине - udev не перечитывает их сам. Нужны udevadm control --reload и trigger.
- rmmod ругается Module is in use - модуль занят (Used by в lsmod не ноль). Сначала освободите потребителей.
- Выполните lsmod и modinfo на любой загруженный модуль, найдите строки depends и parm.
- Загрузите учебный модуль dummy через modprobe, проверьте его в lsmod, затем выгрузите через modprobe -r.
- Создайте /etc/modprobe.d/lab.conf с blacklist для dummy и проверьте сухим прогоном modprobe -n -v dummy, что загрузка заблокирована по алиасу.
- Включите net.ipv4.ip_forward через sysctl -w, убедитесь чтением, потом закрепите файлом в /etc/sysctl.d и примените sysctl --system.
- Напишите простое udev-правило на любое USB-устройство (по idVendor из udevadm info), перечитайте правила и проверьте появление симлинка в /dev.
- Сломайте и почините: удалите запись модуля из modules.dep, повторите modprobe (получите ошибку), восстановите через depmod -a.
- Чем принципиально отличается modprobe от insmod и почему insmod не умеет работать с зависимостями?
- Какой файл и какая команда отвечают за карту зависимостей модулей, и когда её нужно пересобирать вручную?
- Чем blacklist отличается от строки install <модуль> /bin/false и в каком случае blacklist не сработает?
- В чём смысловая разница между /etc/modprobe.d и /etc/modules-load.d, и какой сервис читает второй?
- Как сделать параметр ядра net.ipv4.ip_forward постоянным после перезагрузки и какой командой применить все файлы конфигурации сразу?
- Почему после правки .rules устройство не переименовалось и какие две команды udevadm это исправляют?