Сразу к делу: ядро Linux почти всегда само решает, в каком порядке грузить модули, потому что зависимости разрешаются автоматически. Если модули «загружаются не в том порядке», обычно это не порядок, а конфликт: два модуля дерутся за одно устройство, или модуль грузится раньше, чем готово его оборудование. Лечится это тремя инструментами: файлами в /etc/modules-load.d/ для принудительной загрузки по имени, директивами softdep и blacklist в /etc/modprobe.d/ для управления порядком и запретами. Ниже каждый случай разобран отдельно.
На самом деле у ядра нет «очереди модулей», которую ты задаёшь руками. Загрузка модуля запускается по трём причинам:
/etc/modules-load.d/ или в списке модулей внутри initramfs.Порядок в этом процессе вторичен. Если модуль A требует модуль B, ядро сначала загрузит B, потом A, независимо от того, кто из них раньше попал в список. Поэтому «неправильный порядок» на практике означает одно из двух: либо модуль загрузился, но его оборудование ещё не готово (типично для Wi-Fi и звука), либо два модуля конфликтуют за одно устройство. Классика конфликта: nouveau и nvidia на одной видеокарте.
Решает не «первый», а «нужный». При загрузке ядро опрашивает шины (PCI, USB и другие), находит устройства и ищет для каждого подходящий модуль. Поиск идёт по базе modules.alias, которую собирает depmod. Если модуль подходит устройству по alias, ядро грузит его и все его зависимости.
Отсюда два практических вывода.
Первый: если устройство не подхватилось, чаще всего виноват не порядок, а отсутствие alias. Проверяется это так:
modinfo -a имя_модуля
Второй: если два модуля подходят одному устройству, ядро выберет тот, чей alias совпадёт точнее. Тут и начинаются «конфликты порядка»: nouveau и nvidia оба претендуют на видеокарту NVIDIA, и кто загрузится первым, тот и займёт устройство.
Иногда alias приходится прописывать вручную. Директива alias в /etc/modprobe.d/ привязывает имя устройства к модулю:
# /etc/modprobe.d/aliases.conf
alias char-major-10-175 agpgart
Такие записи ядро использует, когда устройство не подходит ни одному модулю по стандартному правилу.
Для принудительной загрузки модуля по имени при старте системы есть каталог /etc/modules-load.d/. Кладёшь туда файл с расширением .conf, по одному имени модуля на строку:
# /etc/modules-load.d/v4l2loopback.conf
v4l2loopback
usbhid
Имена указываются без расширения .ko и без пути. Такой файл заставляет systemd загрузить модуль на раннем этапе загрузки через сервис systemd-modules-load. Это удобно для модулей, которые не подхватываются автоматически: виртуальные камеры v4l2loopback, uinput, br_netfilter и подобные.
Правила те же, что и для modprobe.d: файл обязан заканчиваться на .conf, иначе он игнорируется. Файлы читаются в алфавитном порядке, поэтому при желании можно использовать те же числовые префиксы. Но помни: modules-load.d задаёт факт загрузки, а не строгий порядок. Если тебе нужно «сначала A, потом B», этот каталог не помощник. Для порядка есть softdep.
Директива softdep (soft dependency, мягкая зависимость) живёт в /etc/modprobe.d/ и говорит: перед загрузкой модуля X подгрузи модули из pre:, а после загрузки X подгрузи модули из post:.
# /etc/modprobe.d/nvidia.conf
softdep nvidia pre: nvidia-drm
Здесь перед nvidia загрузится nvidia-drm, что нужно для корректной работы DRM и Wayland. Ещё пример: если звуковая карта требует, чтобы сначала поднялся модуль шины:
softdep snd_hda_intel pre: snd_hda_core
softdep не создаёт жёсткую зависимость: если модуль из pre: не найдётся, загрузка основного модуля всё равно продолжится. Это «пожелание порядка», а не блокировка.
Ещё один сценарий: две видеокарты, от AMD и Intel, и ты хочешь, чтобы первой поднялась карта AMD. Тогда:
# /etc/modprobe.d/gpu-order.conf
softdep i915 pre: radeon
Порядок загрузки драйверов тут влияет на то, какая карта станет основной для Xorg и Wayland. Без softdep ядро поднимет обе карты в том порядке, в каком их увидит на шине, а он меняется от загрузки к загрузке.
Если модуль загружается слишком рано и ломает работу другого, его можно выключить. Способов два.
Первый: blacklist. Модуль перестанет подхватываться автоматически по alias:
# /etc/modprobe.d/blacklist.conf
blacklist nouveau
Классический пример: перед установкой драйвера NVIDIA модуль nouveau блокируют, чтобы он не перехватил видеокарту раньше nvidia. Подробно установка драйвера разобрана в статье «Драйвер NVIDIA на Arch Linux».
Второй способ: директива install. Она полностью переопределяет команду загрузки модуля. Чтобы модуль вообще никогда не загружался:
# /etc/modprobe.d/blacklist.conf
install uas /bin/false
Теперь любая попытка загрузить uas выполнит /bin/false и завершится ошибкой. Разница с blacklist: blacklist отключает только автозагрузку по alias, а install /bin/false блокирует и явную загрузку через modprobe uas. Если модуль нужен как зависимость другого модуля, blacklist его не остановит, а install /bin/false остановит.
Файлы в /etc/modprobe.d/ обрабатываются в алфавитном порядке. Это важно, потому что при одинаковых настройках побеждает последний прочитанный файл. Отсюда соглашение о префиксах:
/etc/modprobe.d/00-defaults.conf
/etc/modprobe.d/10-nvidia.conf
/etc/modprobe.d/99-custom.conf
Если в 00-defaults.conf стоит options snd_hda_intel index=0, а в 99-custom.conf стоит options snd_hda_intel index=1, применится значение из 99-custom.conf. Поэтому свои правки клади в файл с большим числовым префиксом, а настройки пакетов оставляй в файлах с меньшим. Пакеты Arch кладут свои файлы в /usr/lib/modprobe.d/, а твои правки в /etc/modprobe.d/: файлы из /etc читаются после /usr/lib и перекрывают их.
Тот же принцип работает для звуковых карт. Если у тебя две карты и ты хочешь зафиксировать их порядок:
# /etc/modprobe.d/50-sound.conf
options snd_hda_intel index=0,1
Индекс задаёт порядок регистрации карт: первая карта получит index=0, вторая index=1. Без этого порядка карты могут меняться местами после перезагрузки, и звук уходит не в ту колонку.
Порядок загрузки виден в /proc/modules: первая строка это модуль, загруженный первым.
cat /proc/modules
В каждой строке пять полей: имя модуля, размер в памяти, счётчик использований, список зависимостей и адрес загрузки. Поле зависимостей полезно: если у модуля есть зависимости, они перечислены через запятую и загружены раньше него.
То же самое через lsmod, только без адресов и размеров:
lsmod
Если нужно понять, кто и когда загрузил модуль, смотри dmesg:
dmesg | grep -i module
А чтобы узнать, какие модули подхватились для конкретного устройства, используй lspci -k:
lspci -k | grep -A 3 -i vga
Команда покажет видеокарту и модуль, который её обслуживает. Если там nouveau, а ты ждёшь nvidia, значит, блокировка не сработала или драйвер не установлен.
Сначала проверь, что твои файлы вообще читаются. Имя файла в /etc/modprobe.d/ должно заканчиваться на .conf, иначе он игнорируется. Потом пересобери зависимости модулей:
depmod -a
depmod -a перегенерирует modules.dep и modules.alias. Это обязательно после ручной установки модуля или правки файлов модулей. Без этого ядро может не найти модуль или найти устаревшие зависимости.
Дальше проверь, не перекрывает ли твой файл другой. Помни про алфавитный порядок: если пакет положил options в /usr/lib/modprobe.d/, а ты дублируешь её в /etc/modprobe.d/ с меньшим префиксом, твоя строка может проиграть.
Перед перезагрузкой можно посмотреть, какие зависимости и порядок modprobe вычислит для модуля, без реальной загрузки:
modprobe --show-depends nvidia
Команда выведет цепочку: какие модули подтянутся и в каком порядке. Если в выводе нет ожидаемого pre: или post:, значит, твой файл softdep не читается или перекрыт другим.
Если модуль не загружается вовсе, а не «не в том порядке», это отдельная история: разбор типичных случаев есть в статье «Пропал модуль Wi-Fi после обновления». А если проблема в initramfs, модули, которые грузятся до монтирования корня, настраиваются в mkinitcpio, об этом написано в статье «mkinitcpio подробно: хуки и модули».
Общий порядок диагностики любой проблемы с ядром и модулями описан в статье «Методика решения проблем в Arch Linux».
Скорее всего нет. Проверь dmesg на ошибки конкретного модуля. Частая причина: модуль загрузился, но прошивка не подхватилась, или устройство требует параметр. Порядок редко бывает первопричиной, чаще это конфликт или отсутствие firmware.
/etc/modules-load.d/ только заставляет загрузить модуль по имени при старте. /etc/modprobe.d/ управляет поведением: опции, alias, blacklist, softdep, install. Порядок и запреты это modprobe.d, принудительная загрузка это modules-load.d.
Если модуль грузится на раннем этапе, до монтирования корня, да, пересобери initramfs командой mkinitcpio -P. Если модуль нужен уже после старта системы, правки в /etc/modprobe.d/ применяются сразу, пересборка не нужна.
Проверь, что файл заканчивается на .conf и лежит в /etc/modprobe.d/. Потом посмотри, не тянет ли модуль другой модуль как зависимость: blacklist не мешает загрузке по зависимости. В этом случае используй install имя_модуля /bin/false.
Порядок загрузки модулей в Linux почти всегда решается автоматически через зависимости и alias. Если что-то грузится «не так», ищи конфликт или раннюю загрузку, а не строй очередь вручную. Для принудительной загрузки используй /etc/modules-load.d/, для порядка и запретов: softdep, blacklist и install в /etc/modprobe.d/. Помни про алфавитный порядок файлов и префиксы 00-, 10-, 99-, а после ручных правок модулей прогоняй depmod -a.
Задай вопрос в чате — отвечаем быстро, по делу и без воды.
Комментарии