Свежая Wi-Fi карта или новая видеокарта в системе трехлетней давности отказываются работать: модуль ядра о таких устройствах просто не знает. Ставить новый выпуск дистрибутива ради одного адаптера не обязательно, потому что ядро обновляется отдельно от остальной системы. Разберем реальный порядок действий: определение минимальной версии ядра под конкретный чип, установка mainline-сборки на Ubuntu 20.04 или Debian 11, пересборка модулей DKMS, подкладывание свежих прошивок и откат, если что-то пошло не туда.

Отчего переустановка дистрибутива не единственный путь

У старых выпусков есть штатные механизмы обновления ядра, и проверять стоит сначала их. В Ubuntu 20.04 мета-пакет linux-generic-hwe-20.04 подтягивает ядро 5.15 из стека HWE. В Debian 11 каталог bullseye-backports в свое время предлагал ветку 6.1, а Debian 12 получает более новые ядра из bookworm-backports. Если нужный драйвер появился в 5.15 или 6.1, этого пути достаточно: обновления безопасности приходят автоматически, ядро подписано и собрано под конкретный дистрибутив. Mainline нужен, когда требуемая поддержка появилась только в 6.2 или новее, либо когда стек HWE уже исчерпан. Разница в обслуживании существенная: дистрибутивное ядро обновляет сам дистрибутив, а mainline-сборки одноразовые, и следить за ними придется вручную. Родственный путь - сборка ядра из исходников: к пакетам build-essential, libncurses-dev, flex и bison добавляется конфигурация через make olddefconfig, затем make -j$(nproc), make modules_install и make install. На скромном ноутбуке сборка занимает час-полтора, зато доступна любая версия и собственные патчи. Готовые mainline-пакеты экономят вечер, компиляция дает полный контроль, а HWE и backports - минимум ответственности. Выбор зависит от того, сколько времени хозяин машины готов уделять обслуживанию. Хуже всего вариант с полной переустановкой на новый выпуск: вместе с ядром приедут новые версии библиотек, переписанные конфиги и часы настройки. Ядро решает проблему точечно, без побочных эффектов.

Определение минимальной версии ядра под оборудование

Сначала фиксируют точку отсчета командой uname -r, затем опознают устройство и проверяют, видит ли его текущее ядро:

lspci -nn | grep -iE 'net|vga|usb'
lspci -k
dmesg | grep -i firmware

Строка Kernel driver in use в выводе lspci -k показывает привязанный модуль; если ее нет, драйвер не прикрепился. Записи вида failed to load firmware в журнале говорят о другой половине проблемы - прошивках, о них ниже. Дальше выясняют, в какой версии ядра появился нужный драйвер. Модуль rtw88_8821ce для Realtek RTL8821CE вошел в ядро с версии 5.9, драйвер rtw89 для RTL8852AE появился в 5.16, графика AMD поколения RDNA3 полноценно работает начиная с 6.2, а интегрированная графика Intel Alder Lake уверенно держится на 5.15 и новее. Источники - история коммитов ядра, файлы Kconfig драйверов и открытые базы соответствий конфигураций и версий. Для внешних донглов опознание меняется: lsusb вместо lspci, а журнал читают сразу после подключения. У адаптеров Intel семейства AX210 поддержка появилась в ветке 5.10, но полный набор возможностей Wi-Fi 6E на диапазоне 6 ГГц раскрывается только на новых ядрах, так что минимальная версия и комфортная версия не всегда совпадают. Практическое правило: сначала требуемый минимум из истории драйвера, затем запас в одну-две версии, потому что первые выпуски с новым драйвером традиционно скупы на исправления. Рабочий порядок в итоге выглядит так:

  1. Опознать адаптер по точному идентификатору vendor:device из lspci -nn;
  2. Убедиться, что текущее ядро не привязывает к нему драйвер, через lspci -k;
  3. Найти версию ядра, в которой драйвер появился впервые;
  4. Сравнить ее с ядрами HWE и backports своего дистрибутива;
  5. Если подходящей версии нет, установить mainline-сборку через dpkg;
  6. После перезагрузки проверить dkms status и журнал dmesg.

Установка mainline ядра на Ubuntu из deb пакетов

Каталог mainline на сервере ядра Ubuntu хранит сборки каждой версии в виде deb-пакетов, включая свежие 6.1, 6.6 и 6.12 LTS. В корне каталога висит честное предупреждение: сборки предназначены для отладки и используются на свой риск. Для установки нужны четыре файла версии, например 6.12.10: два пакета linux-headers, пакет linux-image-unsigned и пакет linux-modules. После скачивания их ставят одной командой:

cd ~/Загрузки
sudo dpkg -i linux-modules-6.12.10-061210-generic_*.deb \
  linux-image-unsigned-6.12.10-061210-generic_*.deb \
  linux-headers-6.12.10-061210_*.deb \
  linux-headers-6.12.10-061210-generic_*.deb

Сценарии постустановки сами собирают initramfs и обновляют grub.cfg, поэтому вручную вызывать update-initramfs не требуется. Перед перезагрузкой убеждаются, что образы на месте: ls -lh /boot показывает файлы initrd.img-6.12.10-061210-generic и vmlinuz-6.12.10-061210-generic, а запись о новом ядре уже сидит в меню GRUB. Если /boot вынесен на отдельный раздел, его монтируют до установки пакетов, иначе файлы лягут в корень и загрузчик их не увидит. Кому не по вкусу ручное скачивание, ставит графическую утилиту mainline из соответствующего PPA: она перечисляет доступные ядра, ставит их с зависимостями и присылает уведомления о новых сборках. Популярен и сценарий ubuntu-mainline-kernel.sh: ключ -c показывает последнюю доступную версию, ключ -i устанавливает ее целиком. Нумерация в каталоге прозрачна: версия 6.12.10 соответствует пакетам с суффиксом 061210. Версии с суффиксом rc пропускают: это кандидаты в релизы, созданные для тестирования, а не для ежедневной работы. Пакет модулей весит порядка сотни мегабайт, пакеты заголовков заметно скромнее, поэтому каждая установленная сборка занимает на диске пару сотен мегабайт. Проверить результат помогает dpkg -l с фильтром по шаблону linux-, который покажет весь набор ядер вперемешку с дистрибутивными.

Подпись ядра и Secure Boot при сторонней сборке

Mainline-сборки не подписаны, и прошивка с включенным Secure Boot отвергнет такое ядро с сообщением о провале проверки подлинности. Состояние проверяется командой mokutil --sb-state. На старых ноутбуках Secure Boot часто отсутствует как класс, и вопрос снимается сам. Иначе есть два пути. Первый - отключить Secure Boot в настройках прошивки, что для машины с mainline-ядром вполне разумно. Второй - собственная подпись: генерируется ключ MOK, ядро подписывается утилитой sbsign, а публичный сертификат регистрируется через mokutil --import и подтверждается при следующей загрузке. Тонкость в том, что подписывать придется и модули, собранные DKMS, иначе ядро их не примет при строгой политике проверки. Для первого знакомства с mainline отключение Secure Boot экономит час возни. Дополнительный аргумент в пользу backports звучит неожиданно: ядро из backports подписано дистрибутивом, и с включенной проверкой продолжают грузиться и DKMS-модули без танцев с сертификатами. Если минимально необходимая версия ядра доступна через backports, это вариант по умолчанию, а mainline остается для случаев, когда нужный драйвер еще новее.

Пересборка модулей DKMS под новое ядро

Модули вне ядра - видеодрайвер NVIDIA, VirtualBox, устаревшие Wi-Fi драйверы вроде broadcom-wl - живут благодаря DKMS, который пересобирает их под каждое новое ядро. Состояние показывает dkms status:

dkms status
nvidia/550.107.02, 6.12.10-061210-generic, x86_64: installed

Перед перезагрузкой в новое ядро должны стоять пакеты dkms и linux-headers именно той версии: без заголовков сборка упадет, а драйвер останется в прошлом ядре. После загрузки в свежую версию команда uname -r подтверждает, что грузится именно она, а journalctl -k -b с фильтром по словам nvidia и firmware показывает, что модуль встал и прошивки подобрались. Для графики NVIDIA быстрой проверкой служит nvidia-smi: утилита выводит модель карты и версию драйвера, значит, модуль собрался и загрузился. Важная деталь про NVIDIA: предкомпилированные модули из репозитория дистрибутива привязаны к ABI дистрибутивного ядра и с mainline не работают, поэтому нужен пакет вида nvidia-driver-550-dkms, который собирается на месте. Если сборка сорвалась, журнал лежит в /var/lib/dkms внутри каталога модуля, и там же видна точная причина: чаще всего несовместимый API или отсутствие заголовков. Отдельная осторожность с ZFS: старые выпуски OpenZFS против новых ядер не собираются, и машина с ZFS-корнем остается на дистрибутивном ядре, пока OpenZFS не обновят. Ручной запуск пересборки выглядит так: dkms autoinstall -k 6.12.10-061210-generic собирает все зарегистрированные модули под выбранное ядро. VirtualBox живет по тем же правилам через пакет virtualbox-dkms, а сценарий vboxconfig пересобирает модуль заново после смены ядра. С включенной строгой проверкой подписей каждый собранный модуль требует собственной подписи, и этот факт стоит выяснить до перезагрузки, а не после.

Прошивки linux firmware как вторая половина поддержки

Ядро загружает микропрограммы устройств из каталога /lib/firmware, и новому железу нужны свежие файлы прошивок, которых в старом дистрибутиве нет. Симптомы узнаваемые: Wi-Fi карта видна в lspci, но не находит ни одной сети, видеокарта инициализируется со скрипом, а в dmesg сыплются строки failed to load firmware. Пакет linux-firmware из нового выпуска Ubuntu на старую систему обычно ставится без конфликтов, поскольку это набор файлов данных. Более аккуратный путь - скопировать в /lib/firmware только недостающие файлы для своего устройства, например блобы mt7921 для MediaTek или файлы amdgpu для новой видеокарты, сохранив структуру подкаталогов, и выполнить update-initramfs -u. После такой подкладки устройство оживает даже на ядре, которое дистрибутив официально не поставляет. Перезагрузка не всегда обязательна: пара команд modprobe -r mt7921e и modprobe mt7921e заставляет драйвер перечитать прошивку на живой системе. Учитывать стоит и раннюю загрузку: часть драйверов забирает прошивки из initramfs, поэтому после копирования файлов выполняют update-initramfs -u, чтобы блобы попали в загрузочный образ. Свежие выпуски linux-firmware весят несколько сотен мегабайт, и раздувание всего пакета ради одного файла - личное решение хозяина системы.

Откат и жизнь на двух ядрах параллельно

Главное преимущество схемы в том, что дистрибутивное ядро никуда не девается. Меню GRUB хранит пункт Advanced options, где доступны все установленные ядра, и при любом сбое нового машина грузится со старого одним выбором. Откат в чистый вид выполняется удалением пакетов:

sudo dpkg -r linux-image-unsigned-6.12.10-061210-generic
sudo dpkg -r linux-modules-6.12.10-061210-generic

Дисциплина обслуживания простая: apt mainline-ядра не трогает и обновления к ним не подтягивает, поэтому исправления безопасности требуют установки новой сборки вручную. Пара опций GRUB_DEFAULT=saved и GRUB_SAVEDEFAULT=true избавляет от ручного выбора при каждом старте: меню запоминает последний удачный вариант. Хоть одно дистрибутивное ядро оставляют навсегда, потому что оно остается страховкой на случай, когда свежая сборка после обновления прошивок перестала подходить. Для постоянной работы имеет смысл выбрать LTS-ветку вроде 6.12, которая живет дольше прочих, и раз в месяц заглядывать в каталог mainline за свежими сборками. Раз в месяц имеет смысл удалять промежуточные сборки, оставляя актуальную LTS и дистрибутивное ядро: фильтр dpkg -l по шаблону linux- подскажет лишнее, а удаление освобождает по несколько сотен мегабайт. Мелкий, но реальный камень - объем /boot: при разделе на 512 МиБ два ядра с initramfs помещаются впритык, поэтому перед установкой сборки проверяют свободное место командой df -h /boot. Финальная картина радует: старый дистрибутив со всем привычным окружением, новое ядро с поддержкой купленного на днях адаптера и пара прошивок в /lib/firmware. Переустановки системы не потребовалось, а железо заработало в первый вечер.