Ядро в дистрибутиве уже собрано и обновляется пакетным менеджером, поэтому в 2026 году собирать его руками нужно редко. Но ситуации остаются: нужна свежая фича из mainline, которой нет в репозитории, требуется наложить патч под специфичное железо или баг-фикс из апстрима, надо отключить лишние подсистемы для встраиваемого устройства или включить отладочные опции для воспроизведения проблемы. Экзамен 201.2 проверяет, что вы понимаете весь конвейер: где взять исходники, как сформировать .config, как собрать, установить модули и образ, сгенерировать initramfs и прописать ядро в загрузчик. Этим и займёмся.

Как это работает
Исходники ядра - это дерево из десятков тысяч файлов на C и ассемблере плюс система сборки на базе make (Kbuild). Сердце процесса - файл .config в корне дерева. В нём для каждой опции ядра записано одно из трёх состояний: y (вкомпилировать в монолитный образ vmlinuz), m (собрать как загружаемый модуль .ko) или не задано (выключено). От этого файла зависит абсолютно всё, что соберётся.
Собрать всё подряд нереально и не нужно, поэтому .config почти всегда берут за основу готовый и правят точечно. Источников основы три: defconfig (минимальный разумный конфиг под архитектуру от мейнтейнеров), конфиг работающего ядра из /boot/config-$(uname -r) или /proc/config.gz, и старый .config, который надо привести к новой версии через oldconfig.
Сборка даёт два артефакта. Первый - сам образ ядра (на x86 это bzImage, после установки лежит как /boot/vmlinuz-ВЕРСИЯ). Второй - модули, которые ставятся в /lib/modules/ВЕРСИЯ. Но ядру при старте нужны драйверы для того, чтобы вообще добраться до корневой ФС (контроллер диска, LVM, LUKS, файловая система). Если эти драйверы собраны модулями, возникает курица и яйцо: модуль лежит на диске, который ещё не смонтирован. Решение - initramfs: маленький временный корень в оперативке, куда заранее кладут нужные модули и скрипты. Загрузчик подаёт ядру и vmlinuz, и initramfs, ядро монтирует initramfs, подгружает драйверы, находит настоящий корень и пересаживается на него.
Последний шаг - рассказать про новое ядро загрузчику (GRUB2 или systemd-boot). Современные дистрибутивы делают это автоматически через хуки kernel-install и /etc/kernel/postinst.d, поэтому при ручной сборке надо либо встроиться в эти механизмы, либо обновить конфиг загрузчика руками.
Команды и примеры
Получение исходников. Tarball с kernel.org (в 2026 актуальна ветка 6.x):
Код: Выделить всё
cd /usr/src
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.12.30.tar.xz
tar xf linux-6.12.30.tar.xz
cd linux-6.12.30
Код: Выделить всё
# Debian/Ubuntu
apt install linux-source
tar xf /usr/src/linux-source-*.tar.xz -C /usr/src
# RHEL/Fedora - через пакет с исходником
dnf download --source kernel
rpm -i kernel-*.src.rpm
Код: Выделить всё
# взять рабочий конфиг как основу
zcat /proc/config.gz > .config # если включён CONFIG_IKCONFIG_PROC
# или
cp /boot/config-$(uname -r) .config
make oldconfig # дотягивает конфиг до новой версии, спросит про новые опции
make olddefconfig # то же, но новым опциям молча даёт значения по умолчанию
Код: Выделить всё
make defconfig # разумный дефолт под архитектуру
make menuconfig # текстовое меню (нужен пакет ncurses-devel / libncurses-dev)
make nconfig # альтернативное меню
make localmodconfig # урезает конфиг до реально загруженных сейчас модулей (lsmod)
Код: Выделить всё
make -j$(nproc) # собрать образ и модули
# результат: arch/x86/boot/bzImage и куча .ko
Код: Выделить всё
make modules_install # кладёт модули в /lib/modules/6.12.30/
make install # копирует ядро в /boot, зовёт kernel-install
Код: Выделить всё
# RHEL/Fedora/SUSE - dracut
dracut --force /boot/initramfs-6.12.30.img 6.12.30
# Debian/Ubuntu - initramfs-tools
update-initramfs -c -k 6.12.30
# или напрямую
mkinitramfs -o /boot/initrd.img-6.12.30 6.12.30
Добавление в загрузчик:
Код: Выделить всё
# GRUB2: Debian/Ubuntu
update-grub
# GRUB2: RHEL/Fedora
grub2-mkconfig -o /boot/grub2/grub.cfg
# где kernel-install и BLS - просто скинуть запись
kernel-install add 6.12.30 /boot/vmlinuz-6.12.30
- Забыли поставить заголовки и тулчейн: нет gcc, make, fl:ex, bison, libelf-dev/elfutils-libelf-devel, libssl-dev/openssl-devel. Сборка падает на ранней стадии.
- Драйвер корневого диска или ФС собран модулем (m), но не попал в initramfs - получаете kernel panic "unable to mount root fs". Либо вкомпилируйте такие драйверы в ядро (y), либо проверьте, что dracut их включил.
- make localmodconfig режет всё, что не загружено прямо сейчас. Не воткнут USB-адаптер - после перезагрузки он не заработает. Удобно, но коварно.
- Отключили CONFIG_MODVERSIONS или сменили версию, а старые external-модули (DKMS, проприетарный драйвер) не пересобраны - они не загрузятся.
- make install не перезаписывает initramfs, если вы не пересобрали его под ТУ ЖЕ версию: правите .config, но имя ядра то же - старый initramfs остаётся, изменения не применяются. Всегда явно пересобирайте initramfs.
- Один и тот же LOCALVERSION/имя ядра у двух сборок: новая затирает модули старой в /lib/modules. Меняйте суффикс через CONFIG_LOCALVERSION или make ... LOCALVERSION=-test.
- На виртуалке (не на проде) поставьте тулчейн: в Debian/Ubuntu build-essential, libncurses-dev, bison, flex, libssl-dev, libelf-dev; в Fedora/RHEL группу "Development Tools" плюс ncurses-devel, openssl-devel, elfutils-libelf-devel.
- Скачайте с kernel.org свежий stable-tarball ветки 6.x, распакуйте, зайдите в каталог.
- Скопируйте конфиг текущего ядра в .config и выполните make olddefconfig.
- Через make menuconfig задайте свой суффикс в General setup -> Local version и сохраните.
- Соберите ядро командой make -j$(nproc), затем make modules_install и make install.
- Сгенерируйте initramfs нужным для вашего дистрибутива инструментом (dracut или update-initramfs) под новую версию.
- Обновите загрузчик (update-grub или grub2-mkconfig), перезагрузитесь, выберите новое ядро и проверьте uname -r.
- Чем отличаются значения y, m и пустое для опции в .config и как это влияет на артефакты сборки?
- В чём разница между make oldconfig, make olddefconfig и make localmodconfig?
- Зачем нужен initramfs и при каких настройках ядра без него можно обойтись?
- Какие инструменты генерируют initramfs в семействах Debian и RHEL и чем они отличаются по подходу?
- Что делает make modules_install и почему важно не пересекать имена/версии ядер?
- Какие шаги выполняет make install в современном дистрибутиве и как новое ядро попадает в меню GRUB2?