Learning Platform
Глоссарий Troubleshooting
Урок 15.01 · 20 мин
Начальный
BootBIOSUEFIMBRGPTinitramfsKernel

Boot stages — от power-on до login prompt

Вы нажали кнопку питания. Через 10-30 секунд видите login prompt или GUI. Между этими двумя моментами происходит сложный балет из firmware, bootloader, kernel и userspace. Если что-то сломалось — сервер не грузится, и DBA в 3 утра должен понять, на какой стадии. В этом уроке — полный путь загрузки Linux на современном x86_64-сервере: firmware (BIOS/UEFI) -> partition table (MBR/GPT) -> bootloader -> kernel -> initramfs -> init/systemd -> login.

Каждая стадия имеет своё назначение и свои способы сломаться. Понимая их, вы будете уверенно идти в rescue mode, читать GRUB сообщения и не пугаться “kernel panic”.


Big picture: 7 этапов загрузки

Полный путь загрузки Linux на x86_64
1. PowerCPU подаётся питание, выходит из reset state. Первая инструкция выполняется по адресу 0xFFFFFFF0 (реальный режим x86) или из firmware ROM на UEFI
2. FirmwareBIOS (старый, до 2010) или UEFI (новый). POST -- self-test железа. Инициализация CPU, RAM, чипсета. Выбор boot device по приоритету в Setup
3. BootloaderGRUB или systemd-boot. Загружается из MBR (legacy) или EFI System Partition (UEFI). Показывает меню выбора OS, загружает kernel + initramfs в RAM
4. Kernelvmlinuz распакован, kernel выполняется. Инициализация: detect CPU, memory, базовые драйверы, mount initramfs как rootfs (временный)
5. initramfsМинимальная rootfs в RAM. Содержит модули нужные для mount реального root -- LVM, dm-crypt, NFS, FC. Запускает /init -- скрипт, который монтирует настоящий root
6. switch_rootПосле mount настоящего root -- pivot_root, освобождение initramfs. Теперь / -- настоящая файловая система. Запускается /sbin/init (PID 1)
7. systemdPID 1 -- systemd. Поднимает targets, юниты, сервисы по графу зависимостей. Параллельно запускает sshd, nginx, getty. Готов к login

Время на каждый этап на типичном сервере:

  • BIOS/UEFI POST — 5-30 секунд (особенно на серверах с проверкой памяти, RAID-инициализацией).
  • Bootloader — 1-5 секунд (часто плюс таймаут показа меню).
  • Kernel init — 1-3 секунды.
  • initramfs — 1-3 секунды.
  • systemd targets — 5-30 секунд (зависит от сервисов).

systemd-analyze покажет точные числа:

$ systemd-analyze
Startup finished in 6.234s (firmware) + 2.187s (loader) + 1.456s (kernel) + 12.234s (userspace) = 22.111s
graphical.target reached after 12.234s in userspace.

$ systemd-analyze blame | head
4.234s NetworkManager-wait-online.service
3.187s docker.service
2.456s plymouth-quit-wait.service
1.987s lvm2-activation-net.service
...

blame — хит-парад сервисов по времени запуска. Часто увидите, что 80% времени съедает один сервис.


Этап 1-2: BIOS vs UEFI

BIOS (Basic Input/Output System) — стандарт с 1981 года. 16-битный код, режим реальной адресации, ограничения: жёсткий диск максимум 2 ТБ (через MBR), bootloader должен поместиться в первые 512 байт диска.

UEFI (Unified Extensible Firmware Interface) — современная замена с 2005 года. 32/64-битная среда с собственной файловой системой, поддержкой GPT (диски до 8 ZB), Secure Boot, графического интерфейса, network boot из коробки.

Узнать, какой режим у вашей машины:

# Если есть /sys/firmware/efi -- грузились через UEFI
$ ls /sys/firmware/efi 2>/dev/null && echo "UEFI" || echo "BIOS"
config_table
efivars
fw_platform_size
...
UEFI

# Или через efibootmgr:
$ sudo efibootmgr
BootCurrent: 0001
Timeout: 0 seconds
BootOrder: 0001,0000
Boot0000* Ubuntu        HD(1,GPT,...)/File(\EFI\ubuntu\shimx64.efi)
Boot0001* PXE Network   PciRoot(0x0)/Pci(0x1c,0x4)/Pci(0x0,0x0)/MAC(...)

Современные серверы (2020+) — почти всегда UEFI. Старые системы или специфические VM (qemu без OVMF) — могут быть BIOS.

POST (Power-On Self-Test) — что делает firmware при включении:

  1. Проверяет наличие CPU, RAM, базовых устройств.
  2. Инициализирует RAM (memory training — иногда занимает 10+ секунд на серверах с большим объёмом).
  3. Загружает drivers для устройств (option ROMs: RAID-контроллеры, сетевые карты).
  4. Запускает boot manager.

Этап 3: Boot device selection

Firmware решает, откуда грузиться, по boot order. Этот порядок хранится:

  • В BIOS — в CMOS NVRAM.
  • В UEFI — в EFI variables (см. efibootmgr).

Типичный порядок: USB -> DVD -> локальный диск -> сеть (PXE).

Когда firmware читает диск:

  • MBR-схема (legacy BIOS). Первые 512 байт диска = MBR. Содержит код bootloader (446 байт), partition table (4 записи x 16 байт), magic 0xAA55. Чтение этих 512 байт — bootloader получает control.
  • GPT-схема (UEFI). На диске специальный раздел ESP (EFI System Partition, FAT32, ~500 МБ, флаг boot,esp). Внутри — файлы .efi (bootloaders). Firmware смотрит EFI variables — какой .efi запускать.
# Посмотреть ESP:
$ ls /boot/efi/EFI/
BOOT  ubuntu

$ ls /boot/efi/EFI/ubuntu/
BOOTX64.CSV  fwupx64.efi  grub.cfg  grubx64.efi  mmx64.efi  shimx64.efi

# .efi -- скомпилированные программы под UEFI, не привязанные к x86 ABI Linux
file /boot/efi/EFI/ubuntu/grubx64.efi
# PE32+ executable (EFI application) x86-64

Заметьте: .efi — это PE32+ (Windows EXE!) под x86_64. UEFI использует виндовый формат для своих бинарей — историческая особенность.


MBR vs GPT: partition tables

MBR (Master Boot Record):

  • 512 байт на 0-секторе.
  • 4 primary partitions, или 3 primary + extended (контейнер для logical partitions).
  • Максимум 2 ТБ диск (32-bit sector offsets).
  • Магическое число 0xAA55 в конце.

GPT (GUID Partition Table):

  • Заголовок на secor 1 + копия на последнем секторе (redundancy).
  • 128 partitions по умолчанию (можно больше).
  • 64-bit offsets -> до 8 ZB.
  • Каждый partition имеет UUID, имя, type GUID.
  • CRC32 для целостности.

Посмотреть тип таблицы:

$ sudo parted /dev/sda print | head -5
Model: Samsung SSD 870 EVO 1TB
Disk /dev/sda: 1000GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt           <-- здесь
Disk Flags:

# Или через gdisk:
$ sudo gdisk -l /dev/sda | grep -i guid
Disk identifier (GUID): ABCD1234-...

GPT — современный стандарт, обязателен для UEFI. MBR ещё встречается на VM или старых системах.


Этап 4: kernel загружается в RAM

Bootloader загружает в RAM два файла:

  • vmlinuz — compressed kernel image (/boot/vmlinuz-<version>).
  • initrd / initramfs — initial RAM filesystem (/boot/initrd.img-<version>).

vmlinuz — bzImage, формат zImage (bzImage — big version). Содержит:

  1. Маленький setup code в реальном режиме x86.
  2. Compressed kernel (gz/xz/zstd сжатие).

При запуске kernel:

  1. Setup code инициализирует структуры данных, переходит в protected mode.
  2. Распаковывает себя.
  3. Начинается start_kernel() — main функция kernel.
  4. Инициализирует CPU, memory, IRQ, timers.
  5. Запускает в фоне kernel threads (kworker, kswapd).
  6. Монтирует initramfs как rootfs.
  7. Запускает /init (или /sbin/init) — userspace PID 1.
# Полные kernel-boot messages:
$ dmesg | head -30
[    0.000000] Linux version 6.5.0-21-generic ...
[    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-6.5.0-21-generic root=UUID=5d3e... ro quiet splash
[    0.000000] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'
[    0.000000] BIOS-provided physical RAM map:
[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009f3ff] usable
...

Видим параметры командной строки. root=UUID=... — что мондировать как rootfs. ro — сначала readonly (для безопасного fsck), quiet splash — меньше вывода + splash screen.


Этап 5: initramfs и зачем он нужен

Главный вопрос: kernel умеет читать ext4, почему не смонтировать /dev/sda1 сразу?

Потому что есть три проблемы:

  1. Driver для диска ещё не загружен. kernel компилируется generic, конкретные SCSI/NVMe/RAID-драйверы — модули. Нужны до mount root.
  2. Сложные scenarios. Root на LVM? на dm-crypt (LUKS)? на NFS? на iSCSI? — нужен userspace код для setup.
  3. Asking password. LUKS-зашифрованный root требует passphrase у пользователя.

Решение: initramfs — маленькая rootfs (10-100 МБ), загруженная bootloader’ом вместе с kernel. Содержит:

  • Минимальную /bin, /sbin (busybox).
  • Необходимые kernel modules (драйверы).
  • /init — shell-скрипт, который setup’ит реальный root.
# Посмотреть, что внутри:
$ lsinitramfs /boot/initrd.img-$(uname -r) | head -20
.
bin/
bin/cat
bin/cp
bin/ls
bin/mount
conf/
conf/conf.d/
etc/
init                          <-- main script
lib/
lib/modules/
lib/modules/6.5.0-21-generic/
lib/modules/.../nvme.ko
...

/init делает:

  1. mount /proc, /sys, /dev.
  2. Загружает модули из /lib/modules.
  3. Если LUKS — спрашивает пароль, открывает.
  4. Если LVM — активирует.
  5. mount real root в /root (внутри initramfs).
  6. switch_root /root /sbin/init — меняет rootfs на настоящую, запускает init.

После switch_root initramfs освобождается из памяти. Реальный root монтирован.


Этап 6-7: PID 1 systemd берёт управление

После switch_root запускается /sbin/init — это symlink на systemd.

$ ls -l /sbin/init
lrwxrwxrwx 1 root root 20 May 18 09:12 /sbin/init -> /lib/systemd/systemd

systemd — PID 1. Особый процесс:

  • Не может быть убит сигналами (kernel не доставляет SIGKILL).
  • Если падает — kernel panic.
  • Reap всех zombie-процессов (наследует от ушедших родителей).

systemd читает unit-файлы и поднимает targets (см. урок 13.3). Target multi-user.target — “сервер готов” — все базовые сервисы запущены, getty на TTY открыт, можно логиниться.

Graceful shutdown: preStop, SIGTERM и PID 1 в контейнере

Финальная стадия — getty на /dev/tty1…tty6 (виртуальные консоли) или sshd для удалённого доступа. Когда вы вводите имя пользователя — запускается shell.


Когда что ломается

Стадия 1-2 (firmware): сервер пищит beep-кодами, экран чёрный. Memory не определилась, RAID-контроллер сломан. Обычно требует физического вмешательства.

Стадия 3 (bootloader): “Operating System not found”, “Boot device not found”. MBR/GPT corrupt, или диск умер. Загрузка с LiveCD.

Стадия 4 (kernel): “Kernel panic”, “VFS: Unable to mount root fs on…”. Часто после kernel upgrade сломан initramfs, или root UUID изменился, или потеря драйвера.

Стадия 5 (initramfs): “ALERT! UUID=… does not exist. Dropping to shell”. В initramfs не загрузился нужный модуль (например, для NVMe), или root device не доступен.

Стадия 6-7 (systemd): загружается, но dependency loops, failed mounts, hung services. systemctl --failed, journalctl -b.


Попробуй сам

# 1. Какой режим boot:
ls /sys/firmware/efi 2>/dev/null && echo "UEFI" || echo "BIOS"

# 2. Анализ времени загрузки:
systemd-analyze
systemd-analyze blame | head -10
systemd-analyze critical-chain

# 3. Графика временной диаграммы (SVG):
systemd-analyze plot > boot.svg
# Открыть в браузере

# 4. Полный kernel-лог последней загрузки:
journalctl -k -b | head -40

# 5. Сравнить с предыдущей загрузкой:
journalctl -k -b -1 | head -40

# 6. Содержимое initramfs (внутрь):
mkdir /tmp/initrd && cd /tmp/initrd
zcat /boot/initrd.img-$(uname -r) | cpio -id 2>/dev/null
ls    # видим bin/ etc/ init lib/ usr/
cat init | head -20

# 7. Список boot-сервисов:
systemctl list-units --type=service --state=running | head -20

# 8. Список failed-сервисов:
systemctl --failed

Проверка знанийKnowledge check
Понимаю что после apt upgrade сервер не загружается. На экране -- 'ALERT! UUID=... does not exist. Dropping to a shell!' и появляется initramfs prompt. Что произошло на каком этапе и как починить?
ОтветAnswer
Это классический фейл на стадии 5 (initramfs). Initramfs запустился, kernel работает -- но при попытке смонтировать real root по UUID не нашёл устройство. Возможные причины: 1. Новый kernel без нужного драйвера. Скажем, у вас NVMe-root, и в новом initramfs не включен nvme.ko. После apt upgrade сгенерировался новый initramfs, но кривой. Решение: загрузиться со старого kernel (через GRUB меню -- Advanced options), потом sudo update-initramfs -c -k <new-kernel-version>. 2. UUID реально изменился. Кто-то делал mkfs.ext4 -- новый UUID. /etc/fstab указывает на старый, но в GRUB cmdline в kernel parameters root=UUID=... тоже жёстко прописан. Чинить: загрузиться с LiveCD, узнать актуальный UUID, обновить /etc/default/grub и update-grub. 3. LVM/dm-crypt requires плагины не включены в initramfs. /etc/initramfs-tools/modules может не содержать нужное. /etc/initramfs-tools/conf.d/ должен иметь правильные опции. На initramfs prompt: # Посмотреть что есть из устройств: ls /dev/disk/by-uuid/ # увидеть какие UUID реально доступны ls /dev/ # увидеть /dev/sd*, /dev/nvme* # Если устройство видно (sda, nvme0n1, но нет partition): modprobe -- проверить какие модули доступны modprobe nvme # после загрузки модуля /dev/nvme0n1p1 должно появиться # Если LVM: vgscan && vgchange -ay # Если LUKS: cryptsetup luksOpen /dev/sdaX rootfs # Когда есть устройство, попробовать вручную: mount /dev/<правильный> /root ls /root # должна быть наша система # Если успех -- exit shell, initramfs продолжит работу с тем что вы смонтировали Долгосрочный fix: # Из работающей системы (после восстановления): sudo update-initramfs -u -k all # пересобрать initramfs для всех kernel sudo update-grub # обновить grub.cfg sudo grub-install /dev/sdX # переустановить bootloader на MBR (если BIOS) # для UEFI: sudo grub-install --target=x86_64-efi --efi-directory=/boot/efi Profilaktika: до apt upgrade всегда снимать снапшот VM. На bare metal -- иметь LiveUSB для rescue, знать как chroot из rescue (см. lesson 13.4 troubleshooting-boot).

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 6. В чём ключевая разница между BIOS и UEFI?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 4