Linux под капотом: как система загружается на самом деле (UEFI, GRUB, ядро, initramfs, systemd)

Загрузка Linux обычно выглядит скучно: нажал кнопку, побежали строчки, появился логин. Но внутри за пару секунд происходит цепочка шагов, где любой мелкий косяк превращается в “чёрный экран”, “зависло на A start job is running…” или “почему сервер грузится 3 минуты”.

В этой части рубрики “Linux под капотом” разберу загрузку от момента включения питания до того, как ты видишь приглашение входа. Без мифов и без “оно само”. С командами, где это можно руками потрогать и измерить.

Карта загрузки в двух словах

Если свести весь процесс к “кто за кем”:

  • прошивка (BIOS/UEFI) выбирает, откуда грузиться;
  • загрузчик (чаще GRUB, иногда systemd-boot) загружает ядро и initramfs;
  • ядро Linux поднимает драйверы, память, планировщик и стартует раннее пользовательское окружение из initramfs;
  • initramfs находит корневую ФС и передаёт управление системе (init);
  • init (обычно systemd) запускает сервисы, монтирует всё нужное, поднимает сеть, логин и т.д.

Дальше по шагам, что именно происходит и где это смотреть.

Шаг 1: BIOS/UEFI выбирает, откуда грузиться

На железе первым просыпается прошивка. В старом мире это BIOS, в новом — UEFI. Для Linux админа важны две вещи: режим загрузки (UEFI или Legacy) и то, где лежит загрузчик.

Linux под капотом: как система загружается на самом деле (UEFI, GRUB, ядро, initramfs, systemd)

Как понять, в каком режиме загрузилась система:

[ -d /sys/firmware/efi ] && echo "UEFI" || echo "Legacy BIOS"

Если UEFI, значит где-то есть EFI-раздел (обычно FAT32), и в нём лежат .efi-файлы загрузчика. Если Legacy, история больше похожа на “MBR + GRUB stage”.

Посмотреть EFI-раздел и как он смонтирован:

lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,PARTUUID findmnt /boot/efi || true

Если на сервере внезапно поменялся режим (например, перенос диска, виртуалка, пересоздание VM), дальше начинается цирк: GRUB стоит “не туда”, запись в NVRAM не совпадает, systemd-boot не видит ядро. Поэтому шаг “UEFI/Legacy” — это не формальность, а диагностика в первые 30 секунд.

Шаг 2: загрузчик (GRUB или systemd-boot) и его работа

Загрузчик делает простую, но критичную вещь: выбирает ядро, передаёт параметры командной строки, подцепляет initramfs и запускает ядро. В большинстве дистрибутивов это GRUB. В некоторых системах (особенно чистых UEFI-сборках) может быть systemd-boot.

Если GRUB, то чаще всего конфиг живёт здесь:

ls -l /boot/grub/ /boot/grub2/ 2>/dev/null || true ls -l /etc/default/grub 2>/dev/null || true

Если systemd-boot:

bootctl status 2>/dev/null || true ls -l /boot/loader/entries 2>/dev/null || true

Самое полезное в повседневной жизни — параметры ядра. Они решают “какой root”, “как логировать”, “в какой таргет грузиться”, “вырубить ли splash и увидеть ошибки”.

Посмотреть, с чем ядро реально загрузилось:

cat /proc/cmdline

Два параметра, которые часто выручают при отладке загрузки:

  • systemd.unit=rescue.target — загрузка в rescue (минимум сервисов);
  • systemd.unit=emergency.target — ещё жёстче, по сути “влететь в shell и не трогать лишнее”.

Если система падает на монтировании, сети, кривом сервисе — такие режимы позволяют зайти и чинить, а не смотреть на вечный прогресс-бар.

Шаг 3: ядро Linux стартует и пишет первые логи

Ядро загружается в память, распаковывается, инициализирует железо, драйверы, планировщик, память, файловые системы. Всё это видно в kernel ring buffer — то самое, что показывает dmesg.

Посмотреть сообщения ядра текущей загрузки:

dmesg -T | less

А если нужно поймать именно ошибки и предупреждения:

dmesg -T --level=err,warn | less

На этом этапе типовые проблемы выглядят так: “не нашёл диск”, “не поднялся драйвер”, “ждал устройство”, “не смог смонтировать root”. Если root не смонтировался — загрузка дальше не пойдёт. И тут в игру вступает initramfs.

Шаг 4: initramfs — “временная система”, которая ищет твой root

initramfs (или initrd) — это минимальная файловая система в памяти. Внутри скрипты и драйверы, которые нужны, чтобы:

  • подцепить RAID/LVM/шифрование (LUKS);
  • найти нужный диск;
  • смонтировать корень и передать управление основному init.

В Debian/Ubuntu initramfs обычно собирается через update-initramfs. Быстро посмотреть, какие образы есть:

ls -lh /boot/initrd* /boot/initramfs* 2>/dev/null || true uname -r

Пересобрать initramfs для текущего ядра (когда, например, добавил драйвер, поменял LVM, правил hooks):

sudo update-initramfs -u -k "$(uname -r)"

Самый частый сценарий “всё работало, а потом не грузится” — поменяли диски/UUID, правили /etc/fstab, пересобрали RAID, или переехали в другую виртуалку, а initramfs остался со старой картиной мира. В итоге ядро стартует, а root найти не может.

Шаг 5: systemd как PID 1 и почему именно он решает, “быстро” или “долго”

Когда root смонтирован, ядро запускает первый пользовательский процесс — init. На большинстве современных систем это systemd. Он становится PID 1 и дальше дирижирует всем: монтирование, сервисы, сеть, логирование, таймеры, зависимости.

Проверить, кто у тебя PID 1:

ps -p 1 -o pid,comm,args

Посмотреть, во что система загрузилась (target):

systemctl get-default systemctl list-units --type=target --state=active

Вот тут и рождаются “долгие загрузки”. Не потому что “Linux медленный”, а потому что какой-то unit ждёт сеть, диск, DNS, таймаут монтирования или внешний ресурс. systemd честно ждёт, пока истечёт таймаут, и ты получаешь лишние 90 секунд на ровном месте.

Как посмотреть, что тормозит загрузку

systemd даёт три команды, которые я считаю обязательными в арсенале.

Общее время загрузки по этапам (прошивка, загрузчик, ядро, userspace):

systemd-analyze

Самые долгие юниты (не всегда “виновники”, но это отличная зацепка):

systemd-analyze blame | head -n 30

Цепочка зависимостей до конкретного проблемного юнита. Очень помогает, когда “виновник” не тот, кто висит, а тот, кого он ждёт:

systemd-analyze critical-chain

Если видишь что-то вроде dev-disk-by... или network-online.target с большим временем — это классика. Диск не появился вовремя, DNS не поднялся, сетевой “online” ждёт бесконечно, а сервер просто стоит и ждёт, как дисциплинированный.

Где смотреть логи загрузки: journalctl и dmesg

Для диагностики я почти всегда начинаю с лога текущего бут-цикла.

Логи текущей загрузки:

journalctl -b -0

Логи предыдущей загрузки (когда “упало и перезагрузилось”, а ты пришёл уже после):

journalctl -b -1

Только ошибки текущей загрузки:

journalctl -b -0 -p err

Если журнал не сохраняется между перезагрузками, диагностика превращается в гадание. Включается это просто: нужен каталог /var/log/journal и рестарт journald.

sudo mkdir -p /var/log/journal sudo systemctl restart systemd-journald

После этого journalctl -b -1 станет реально полезным, а не “пусто, потому что так решили по умолчанию”.

Мини-лабораторка: измерь загрузку и найди узкое место

Этот блок можно прогнать на любой Ubuntu/Debian (и вообще на большинстве systemd-систем). Ничего опасного, только наблюдение.

1) Зафиксируй времена загрузки и топ медленных юнитов:

systemd-analyze systemd-analyze blame | head -n 25 systemd-analyze critical-chain

2) Найди один долгий юнит и посмотри подробности (что он делает и почему ждёт):

systemctl status ИМЯ_ЮНИТА journalctl -b -0 -u ИМЯ_ЮНИТА --no-pager

3) Проверь, не упёрся ли сервер в ожидание диска/монтажа. Если в выводах часто мелькают монтирования:

systemctl --failed findmnt -a | head cat /etc/fstab

Если в /etc/fstab есть сетевые шары или “второстепенные” диски, которые не всегда доступны, их можно делать более мягкими (например, через nofail и разумные timeout-опции). Но это уже тема для отдельной заметки: “как не убивать загрузку из-за одного капризного диска”.

Что дальше в рубрике

Следующий логичный шаг — разбор systemd глубже: unit-файлы, зависимости, targets, таймеры, почему network-online.target иногда зло, и как делать сервисы так, чтобы они стартовали предсказуемо.

А ещё отдельно стоит разобрать initramfs на реальных кейсах: LUKS, LVM, RAID, перенос дисков, восстановление после кривого fstab. Там много боли, но зато после этого “не грузится сервер” перестаёт звучать как приговор.


blank
Обзор конфиденциальности

На этом сайте используются файлы cookie, что позволяет нам обеспечить наилучшее качество обслуживания пользователей. Информация о файлах cookie хранится в вашем браузере и выполняет такие функции, как распознавание вас при возвращении на наш сайт и помощь нашей команде в понимании того, какие разделы сайта вы считаете наиболее интересными и полезными.