Загрузчик и GRUB
Что делает загрузчик и где живёт GRUB.
Что делает загрузчик
Загрузчик (bootloader) — это программа, которая находит ядро (kernel) на диске, загружает его в память и передаёт ему управление. После включения питания firmware не умеет читать файловую систему и запускать сложное ядро. Оно передаёт эстафету загрузчику, а тот уже разбирается с диском.
Цепочка запуска всегда одна: firmware -> загрузчик -> ядро -> initramfs. Каждое звено делает свой кусок работы и уступает место следующему. initramfs — это временный корень, который ядро распаковывает в память (в rootfs на tmpfs при собранном CONFIG_TMPFS), чтобы подмонтировать настоящий корневой раздел.
Кроме самого ядра загрузчик передаёт ему параметры. Это строка kernel command line: где искать корень, в каком режиме монтировать, что показывать на экране.
# типичная строка параметров ядра
root=/dev/sda2 ro quiet
# root= — какой раздел монтировать как корневой
# ro — примонтировать сначала только на чтение
# quiet — не сыпать логами ядра на экран при загрузке
Посмотреть параметры, с которыми загрузилась текущая система, можно после старта:
$ cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-6.1.0 root=/dev/sda2 ro quiet
GRUB
GRUB (GRand Unified Bootloader) — это загрузчик, который стоит на большинстве Linux-систем. При старте он показывает меню: какое ядро или какую систему запускать. Меню и все настройки GRUB читает из конфига.
$ ls /boot/grub/
grub.cfg fonts i386-pc locale
# grub.cfg — сгенерированный конфиг, который GRUB читает при старте
Файл grub.cfg не пишут руками. Его собирает утилита из шаблонов
в /etc/grub.d/ и настроек в /etc/default/grub. После правки
настроек конфиг пересобирают:
$ update-grub # Debian/Ubuntu
$ grub2-mkconfig -o /boot/grub2/grub.cfg # Fedora/RHEL
GRUB подгружает себя с диска небольшими шагами. Первый крошечный
кусок кода умеет ровно одно: прочитать с диска следующий, побольше.
Тот уже понимает файловые системы, находит grub.cfg, рисует меню
и в итоге загружает выбранное ядро. Единой трёхстадийной схемы
здесь нет, деталей у разных установок хватает.
GRUB умеет chainloading: передать управление другому загрузчику вместо того, чтобы грузить ядро самому. Так запускают, например, Windows: GRUB не понимает его загрузку, поэтому просто отдаёт управление загрузчику Windows.
# фрагмент меню GRUB с chainloading на другой раздел
menuentry "Windows" {
chainloader (hd0,1)+1
}
Где физически лежит первичный код
На старых системах с BIOS первый кусок загрузчика помещается в MBR (Master Boot Record), первый сектор диска размером 512 байт. Первые 446 байт там отведены под код первичного загрузчика, остальное занимает таблица разделов и сигнатура.
$ sudo dd if=/dev/sda bs=512 count=1 | wc -c
512
# весь MBR — ровно 512 байт, код в них не помещается целиком
Именно поэтому загрузчик и делится на шаги: в 446 байт влезает только код, который дотянется до остального загрузчика на диске.
На UEFI картина другая. Здесь загрузчик лежит файлом на отдельном разделе EFI и firmware запускает его напрямую. Больше того, ядро Linux можно собрать с EFI stub, и тогда firmware грузит само ядро как исполняемый файл, вообще без отдельного загрузчика.
Две частые ошибки
Первая: «GRUB — это часть ядра». Нет. GRUB отрабатывает и полностью уходит из памяти до того, как ядро начнёт работать. Это отдельная программа со своей задачей: найти и запустить ядро.
Вторая: «загрузчик — это один файл». Тоже нет. GRUB — набор
компонентов: первичный код в загрузочной области, модули в /boot,
конфиг grub.cfg. Они подгружаются по очереди, а не лежат единым
бинарником.
После того как ядро получило управление и подняло initramfs, запускается первый пользовательский процесс, обычно systemd.
Что важно запомнить
Загрузчик находит ядро на диске, грузит его в память и передаёт управление с параметрами (kernel command line).
Цепочка: firmware -> загрузчик -> ядро -> initramfs.
GRUB читает grub.cfg, показывает меню, подгружает себя с диска
шагами и умеет chainloading на другой загрузчик.
Параметры ядра вроде root=, ro, quiet видно в /proc/cmdline.
MBR — 512 байт, из них 446 под код первичного загрузчика. На UEFI ядро грузится напрямую через EFI stub без отдельного загрузчика.
GRUB — не часть ядра и не один файл, а набор компонентов.
В следующем уроке — initramfs: зачем ядру временный корень в памяти и как он монтирует настоящий.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс