Загрузка Linux: от BIOS/UEFI до systemd

Полная цепочка от включения питания до приглашения логина: кто кого запускает и где именно вмешаться, если система не грузится.

Процесс загрузки — последовательность передачи управления: прошивка (BIOS/UEFI) → загрузчик (GRUB) → ядро + initramfs → PID 1 (systemd) → целевой target.

Зачем это на практике

Пока всё грузится — кажется, что знать этапы незачем. Но в день, когда сервер встаёт в emergency mode из-за битой строки в /etc/fstab или после обновления ядра не находит корневой раздел, понимание цепочки — единственный способ починить. Знание, что где настраивается, превращает панику в десятиминутную правку из GRUB.

Этап 1: прошивка — BIOS или UEFI

После включения управление получает прошивка материнской платы. Она проводит POST (самопроверку оборудования), затем ищет загрузчик.

  • BIOS (старый режим): читает первые 512 байт диска — MBR, там код загрузчика и таблица разделов.
  • UEFI (современный): читает ESP (EFI System Partition, обычно FAT32, смонтирован в /boot/efi) и запускает .efi-файл загрузчика. Поддерживает Secure Boot.
# какой режим используется сейчас
[ -d /sys/firmware/efi ] && echo UEFI || echo BIOS

# содержимое ESP и записи менеджера загрузки UEFI
ls /boot/efi/EFI/
efibootmgr -v

Этап 2: загрузчик GRUB

GRUB 2 — стандартный загрузчик. Его задача: показать меню ядер и загрузить выбранное ядро вместе с initramfs в память, передав ему параметры командной строки. Конфигурация:

/etc/default/grubнастройки (таймаут меню, параметры ядра) — здесь правим
/boot/grub/grub.cfgсгенерированный файл — руками не трогаем
/etc/grub.d/скрипты-генераторы пунктов меню
# изменили /etc/default/grub (например GRUB_CMDLINE_LINUX) — пересобираем конфиг:
sudo update-grub                       # Debian/Ubuntu
sudo grub2-mkconfig -o /boot/grub2/grub.cfg   # RHEL/Fedora

Ключевой приём восстановления: в меню GRUB нажать e, найти строку linux и временно дописать параметр (например systemd.unit=rescue.target или init=/bin/bash), затем Ctrl+X для загрузки. Это разовая правка, она не сохраняется.

Этап 3: ядро и initramfs

GRUB распаковывает ядро и initramfs (initial RAM filesystem) в память. Ядро инициализирует CPU, память, базовые драйверы — и тут возникает проблема курицы и яйца: чтобы смонтировать корневую ФС, нужны драйверы диска/RAID/LVM/шифрования, которые лежат… на этой же ФС. Решение — initramfs: маленький временный корень в оперативной памяти с нужными модулями. Он монтирует настоящий / и передаёт ему управление.

# посмотреть, что внутри initramfs
lsinitramfs /boot/initrd.img-$(uname -r) | head   # Debian/Ubuntu
lsinitrd /boot/initramfs-$(uname -r).img | head   # RHEL/Fedora

# пересобрать initramfs (после смены драйверов/ключей шифрования)
sudo update-initramfs -u                # Debian/Ubuntu
sudo dracut --force                     # RHEL/Fedora

Этап 4: PID 1 — systemd

Смонтировав корень, ядро запускает /sbin/init — это symlink на systemd. С этого момента systemd берёт управление как PID 1, читает default.target и параллельно поднимает весь граф юнитов до достижения цели (обычно multi-user.target или graphical.target). На экране появляется приглашение логина.

# что грузилось дольше всего
systemd-analyze
systemd-analyze blame | head
systemd-analyze critical-chain          # цепочка зависимостей, тормозящая загрузку

Восстановление при поломке загрузки

Типовые сценарии и куда вмешаться:

СимптомГде чинить
чёрный экран, нет меню GRUBзагрузка с live-USB, grub-install + update-grub
новое ядро паникуетв меню GRUB выбрать прошлое ядро (подменю «Advanced»)
встаёт в emergency modeчаще всего битый /etc/fstab; смонтировать / на запись и поправить
забыли пароль rootinit=/bin/bash из GRUB, mount -o remount,rw /, passwd
# типовая правка fstab в emergency mode
mount -o remount,rw /
vi /etc/fstab          # закомментировать битую строку
systemctl daemon-reload
reboot

Как это работает под капотом

Каждый этап знает ровно столько, чтобы найти и запустить следующий, и передаёт ему управление — это эстафета. Прошивка не понимает файловых систем Linux, поэтому GRUB разбит на стадии: крошечный код в MBR/ESP умеет прочитать модули GRUB с /boot, а уже полноценный GRUB читает ФС и конфиг. initramfs существует, потому что монолитное ядро не содержит всех драйверов сразу — их грузят модулями, но модули на диске, до которого ещё нет драйвера; временный RAM-корень разрывает этот круг. Параметры ядра (root=UUID=..., ro, quiet), которые GRUB передаёт строкой, ядро парсит при старте — поэтому правка одной строки в GRUB меняет поведение загрузки целиком.

Частые ошибки

  • Правят /boot/grub/grub.cfg руками — при следующем update-grub изменения затираются. Правильно — /etc/default/grub + пересборка.
  • Сменили драйвер диска или ключ шифрования и забыли update-initramfs -u → система не находит корень.
  • Опечатка в /etc/fstab (неверный UUID, опция) роняет загрузку в emergency mode; помогает опция nofail для некритичных монтирований.
  • В UEFI снесли запись загрузки или отформатировали ESP — машина не видит ОС, лечится efibootmgr/переустановкой загрузчика.
  • Путают multi-user.target и graphical.target при настройке сервера и грузят лишнюю графику.

Итоги

  • Цепочка: прошивка (POST) → GRUB → ядро+initramfs → systemd (PID 1) → target.
  • BIOS читает MBR, UEFI — ESP (/boot/efi); режим виден по /sys/firmware/efi.
  • GRUB настраивается в /etc/default/grub, а grub.cfg генерируется.
  • initramfs — временный RAM-корень с драйверами, чтобы примонтировать настоящий /.
  • Правка строки linux в меню GRUB (клавиша e) — главный приём аварийного восстановления.
Проверьте себя
1. Зачем нужен initramfs, если ядро уже загружено в память?
AЧтобы показать графическую заставку загрузки
BЭто временный корень в RAM с драйверами (диск, LVM, RAID, шифрование), нужными чтобы смонтировать настоящую корневую ФС
CЧтобы хранить логи до запуска journald
DЭто резервная копия ядра на случай паники
2. Вы изменили GRUB_CMDLINE_LINUX в /etc/default/grub. Что нужно сделать, чтобы изменения вступили в силу?
AНичего, GRUB читает /etc/default/grub при каждой загрузке
BОтредактировать /boot/grub/grub.cfg вручную
CПересобрать конфиг: update-grub (или grub2-mkconfig)
DПересобрать initramfs командой update-initramfs