Загрузка 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) и то, где лежит загрузчик.
Как понять, в каком режиме загрузилась система:
[ -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. Там много боли, но зато после этого «не грузится сервер» перестаёт звучать как приговор.