Библиотека — Linux — обновление и управление загрузкой [X]
Шифр
linux-boot-management
Разделы
linux tooling
Сверено
2 сентября — в этот день утверждения статьи сверялись с первоисточниками, а не правился текст
Объём
17 383 знака · 23 раздела · чтения около 20 минут

Linux — обновление и управление загрузкой


Обзор

Процесс загрузки Linux — цепочка передачи управления: firmware (UEFI/BIOS) → bootloader (GRUB2/systemd-boot) → ядро + initramfs → systemd (PID 1). Каждое звено имеет свои механизмы конфигурации, отказоустойчивости и обновления. Параллельно существуют механизмы обновления самого ядра: от классического «установить новый пакет и перезагрузить» до live patching (обновление без перезагрузки) и snapshot-based rollback (Btrfs/ZFS boot environments).

В FreeBSD цепочка проще: UEFI → loader (единый bootloader) → ядро. Обновление через freebsd-update (бинарно) или buildworld/buildkernel (из исходников), boot environments через bectl (ZFS). Linux разнообразнее в инструментах, но сложнее в координации.

Цепочка загрузки

UEFI vs Legacy BIOS

Legacy BIOS (устаревший): MBR → stage 1 bootloader (446 байт в MBR) → stage 1.5 (в gap между MBR и первым разделом) → stage 2 (GRUB core) → ядро. Ограничения: MBR поддерживает до 4 primary partitions, максимум 2 TiB на диск, нет Secure Boot.

UEFI (современный): firmware читает ESP (EFI System Partition, FAT32, обычно /boot/efi) → загружает .efi файл (shimx64.efi при Secure Boot, затем grubx64.efi) → GRUB → ядро. Преимущества: GPT (до 128 partitions, exabyte-scale), Secure Boot (цепочка доверия), EFI variables для управления boot order.

Secure Boot цепочка: UEFI (ключи Microsoft в firmware) → shim (подписан Microsoft, содержит ключ дистрибутива) → GRUB (подписан дистрибутивом) → ядро (подписано) → модули (подписаны). Shim — прослойка, позволяющая дистрибутивам использовать свои ключи без необходимости подписывать каждый файл у Microsoft. MOK (Machine Owner Key) — механизм добавления пользовательских ключей (для DKMS/NVIDIA модулей, см. статью 5). Возможна и полностью своя цепочка доверия, без shim: сгенерировать собственные PK/KEK/db, прошить их в firmware и подписывать загрузчик, ядро и UKI своим ключом; практическая обвязка для этого — sbctl, который заодно ведёт учёт файлов загрузочной цепочки, требующих подписи.

Boot order

efibootmgr управляет UEFI boot entries:

efibootmgr -v                            # список boot entries с деталями
efibootmgr -o 0002,0001,0003             # изменить порядок загрузки
efibootmgr -n 0003                       # следующая загрузка — entry 0003 (одноразово)

GRUB2

Архитектура

GRUB2 (GRand Unified Bootloader) — стандартный bootloader для большинства дистрибутивов. Модульная архитектура: core image загружает модули для ФС, шифрования, сети, GUI. Поддерживает BIOS и UEFI, может читать ext4/XFS/Btrfs/LVM/LUKS напрямую (без помощи ядра).

Конфигурация

Главный конфиг: /boot/grub/grub.cfg (Debian) или /boot/grub2/grub.cfg (RHEL). Не редактировать напрямую — генерируется автоматически.

Источники генерации: /etc/default/grub (основные параметры) + скрипты в /etc/grub.d/ (генераторы menu entries).

# /etc/default/grub — ключевые параметры
GRUB_DEFAULT=0                    # дефолтный entry (число или "saved")
GRUB_TIMEOUT=5                    # секунды ожидания
GRUB_CMDLINE_LINUX="rhgb quiet"   # параметры ядра для всех entries
GRUB_CMDLINE_LINUX_DEFAULT=""     # параметры только для дефолтного entry
GRUB_DISABLE_RECOVERY=false       # показывать recovery entries

# Применить изменения
# Debian/Ubuntu:
update-grub                       # alias для grub-mkconfig -o /boot/grub/grub.cfg
# RHEL/Fedora:
grub2-mkconfig -o /boot/grub2/grub.cfg
# UEFI-системы (RHEL):
grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg

Скрипты /etc/grub.d/: 00_header (base config), 10_linux (Linux entries), 30_os-prober (другие ОС), 40_custom (кастомные entries). Порядок определяется числовым префиксом.

Rescue

При проблемах GRUB может оказаться в rescue shell (минимальное окружение) или command line (полноценная консоль). Recovery:

# Из GRUB command line — загрузка вручную
set root=(hd0,gpt2)
linux /vmlinuz root=/dev/sda2 ro
initrd /initrd.img
boot

# Из rescue shell — сначала загрузить модули
set prefix=(hd0,gpt2)/boot/grub
insmod normal
normal                            # переключиться в полноценный GRUB

# После загрузки системы — переустановить GRUB
# BIOS:
grub-install /dev/sda
# UEFI:
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB
update-grub

Управление ядрами

При установке нового ядра (apt install linux-image-*, dnf install kernel) GRUB автоматически обновляет конфигурацию. Дистрибутивы сохраняют несколько ядер (обычно 2-3) для возможности отката.

# Какое ядро загрузится по умолчанию
grub2-editenv list                        # RHEL
grub-editenv list                         # Debian

# Выбрать конкретное ядро для следующей загрузки
grub2-reboot "Advanced options>Linux 6.1.0-old"   # одноразово
grub2-set-default 1                       # постоянно (по номеру)

# RHEL: grubby — утилита для управления entries
grubby --default-kernel                   # текущее дефолтное ядро
grubby --set-default /boot/vmlinuz-6.12.0-100.fc41.x86_64
grubby --args="debug" --update-kernel=ALL # добавить параметр ко всем ядрам

systemd-boot

Альтернатива GRUB для UEFI-only систем. Минималистичный: не поддерживает BIOS, LVM, LUKS, сетевую загрузку. Читает только ESP (FAT32), ядро и initramfs должны находиться на ESP.

Дефолт в: systemd-based дистрибутивах с UEFI (Pop!_OS, EndeavourOS, Arch при выборе), ClearLinux (EOL). Fedora и Ubuntu экспериментируют.

# Конфигурация: /boot/loader/loader.conf
default @saved
timeout 5
editor  no                        # запретить редактирование entries (безопасность)

# Entries: /boot/loader/entries/*.conf
# /boot/loader/entries/arch.conf
title   Arch Linux
linux   /vmlinuz-linux
initrd  /initramfs-linux.img
options root=UUID=xxxx rw quiet

bootctl install                   # установить systemd-boot
bootctl update                    # обновить
bootctl list                      # показать entries

Преимущество: простота, быстрота (нет GRUB stage loading), автоматическое обнаружение ядер через Boot Loader Specification (BLS). Недостаток: нет поддержки encrypted root без отдельного initramfs, нет BIOS.

Рядом с самим загрузчиком развивается формат UKI (Unified Kernel Image): ядро, initramfs и командная строка упаковываются вместе с EFI-стабом systemd-stub в один PE-файл, который подписывается целиком — ради целостности загрузочной цепочки, включая cmdline. Такие образы кладут в ESP/EFI/Linux/ (записи Type #2 по Boot Loader Specification), где их находит systemd-boot; но UKI сам по себе EFI-приложение, поэтому firmware способно запустить его напрямую, вообще без загрузчика. Собирает UKI утилита ukify из systemd, а дистрибутивные генераторы initramfs вызывают её через свои обёртки: mkinitcpio -U в Arch, dracut --uefi в Fedora.

Обновление ядра

Дистрибутивные механизмы

Debian/Ubuntu: ядро — пакеты linux-image---. При установке автоматически запускаются: depmod (зависимости модулей), update-initramfs (создание initramfs), update-grub (обновление GRUB config). Удаление старых: apt autoremove или ручное apt purge linux-image-<old>. В Ubuntu эта схема уже меняется: генератором initramfs по умолчанию стал dracut — на сервере с 25.10, на десктопе с 26.04 LTS, — вместо initramfs-tools.

RHEL/Fedora: ядро — пакет kernel-. DNF не обновляет ядро in-place, а устанавливает рядом (installonly_limit=3 в dnf.conf — хранить 3 ядра). При установке: depmod, dracut (initramfs), grub2-mkconfig автоматически. dnf remove kernel-<old> для очистки.

Arch: ядро — пакет linux. pacman -Syu обновляет ядро in-place (модули в /lib/modules/ перезаписываются). Gotcha: если не перезагрузиться сразу, загруженные модули могут не соответствовать файлам на диске (модули текущего ядра удалены, новые — для нового ядра). mkinitcpio hook автоматически пересоздаёт initramfs.

Live patching

Обновление ядра без перезагрузки. Kernel Livepatch (CONFIG_LIVEPATCH, с ядра 4.0) — unified framework в mainline-ядре, объединяющий подходы kpatch (Red Hat) и kGraft (SUSE).

Механизм: livepatch использует ftrace для перенаправления вызовов функций. Исходный diff компилируется в .ko модуль, содержащий новые версии функций. При загрузке модуля ftrace hook перенаправляет вызовы старых функций на новые. Переключение per-task: каждый поток переводится в «новый мир» при пересечении границы kernel/userspace. Обычно завершается за секунды.

Ограничения: только замена функций (не структур данных), только security-фиксы (не feature updates), коммерческие сервисы (Red Hat kpatch, SUSE kGraft, Canonical Livepatch) предоставляют готовые патчи за плату. Self-hosted kpatch возможен, но требует полной пересборки ядра для генерации diff. С Linux 6.19 сам kpatch объявлен устаревшим и переведён в режим поддержки: его сборочную часть, kpatch-build, заменяет klp-build, который теперь живёт в дереве ядра (scripts/livepatch/klp-build); поддерживается пока x86-64, arm64 в работе.

# Red Hat kpatch
kpatch list                              # текущие патчи
kpatch load livepatch-<version>.ko       # применить патч
cat /sys/kernel/livepatch/*/enabled      # статус

# Canonical Livepatch (Ubuntu Pro)
canonical-livepatch status
canonical-livepatch enable <token>

Snapshot-based rollback

Btrfs + snapper

snapper (SUSE/openSUSE, доступен в Fedora) автоматически создаёт снэпшоты при обновлениях. Интеграция: zypper/dnf plugin → pre/post snapshot → если обновление сломало систему → выбрать предыдущий снэпшот в GRUB → загрузиться в рабочее состояние.

snapper list                             # список снэпшотов
snapper diff 5..6                        # различия между снэпшотами
snapper undochange 5..6                  # откатить изменения
snapper rollback 5                       # откат с созданием нового snapshot

# grub-btrfs — автоматически добавляет Btrfs snapshots в GRUB menu
# После установки: каждый снэпшот — отдельный boot entry

openSUSE Tumbleweed (rolling release) полагается на snapper как safety net: каждое обновление создаёт snapshot, неудачное обновление откатывается за секунды.

Timeshift

Timeshift — GUI/CLI инструмент для desktop Linux (аналог macOS Time Machine). Поддерживает Btrfs snapshots и rsync. Linux Mint включает Timeshift по умолчанию. Для Btrfs: снэпшоты субтомов @ и @home.

LVM snapshots

Менее элегантно, но работает с ext4/XFS: lvcreate -s -L 10G -n snap /dev/vg0/root. После обновления: если всё работает — удалить snapshot; если нет — lvconvert --merge /dev/vg0/snap + reboot (см. статью 8).

Dist-upgrade: обновление между релизами

Debian/Ubuntu: apt update && apt full-upgrade (внутри релиза), do-release-upgrade (между релизами Ubuntu). Debian: изменить sources.list (bookworm → trixie) → apt update && apt full-upgrade. Рекомендуется snapshot/backup перед major upgrade.

RHEL/Fedora: dnf system-upgrade download --releasever=44 && dnf system-upgrade reboot (Fedora). RHEL: leapp — инструмент для in-place upgrade между major versions (RHEL 8→9). Сложнее, чем Fedora, из-за длинного lifecycle и enterprise constraints.

Arch: rolling release — нет dist-upgrade как события. pacman -Syu — единственная команда обновления. Arch News читать перед каждым обновлением — manual interventions иногда необходимы.

Immutable distributions: Fedora CoreOS (rpm-ostree), NixOS (nix), Silverblue — atomic updates с автоматическим rollback. Системный образ обновляется целиком; при неудаче — загрузка предыдущего deployment.

Практика

# Текущая цепочка загрузки
efibootmgr -v                            # UEFI entries
cat /proc/cmdline                         # параметры текущего ядра
journalctl -b -0 | head -50              # логи текущей загрузки

# Управление ядрами
ls /boot/vmlinuz*                         # установленные ядра
uname -r                                  # текущее ядро

# Debian: установленные ядра
dpkg --list | grep linux-image
# RHEL:
rpm -qa | grep kernel-core

# Проверка GRUB
grub-mkconfig -o /dev/null                # dry-run (проверка без записи)

# Boot timing
systemd-analyze                           # общее время загрузки
systemd-analyze blame                     # время по unit'ам
systemd-analyze critical-chain            # critical path

Нюансы и trade-off'ы

GRUB vs systemd-boot. GRUB — универсальный, но сложный (своя FS-реализация, скрипты, модули). systemd-boot — минималистичный, быстрый, но ограниченный (no BIOS, no LVM, no LUKS root без initramfs). Для серверов с encrypted root и LVM — GRUB единственный выбор. Для UEFI-десктопов — systemd-boot проще и надёжнее.

Live patching — не серебряная пуля. Livepatch покрывает только security-фиксы, не feature updates. Ядро всё равно нужно обновлять и перезагружаться периодически (для structure changes, major updates). Live patching откладывает reboot, не устраняет его. Коммерческие сервисы (Red Hat, SUSE, Canonical Pro) — основные потребители; self-hosted kpatch трудоёмок.

Btrfs rollback vs LVM snapshot. Btrfs snapshot: мгновенный, нулевой overhead, интегрирован с GRUB (grub-btrfs), работает на production. LVM snapshot: COW penalty (каждая запись → дополнительное чтение), ограниченный размер, инвалидируется при переполнении. Для rollback Btrfs объективно лучше.

Kernel in-place update (Arch) gotcha. После pacman -Syu модули старого ядра удалены. Если попытаться загрузить модуль до reboot — ошибка. Частичное решение: пакет linux-lts как fallback-ядро.

GRUB и Btrfs snapshots. grub-btrfs сканирует снэпшоты и добавляет boot entries. При большом количестве снэпшотов (snapper с часовыми snapshot'ами) GRUB menu может стать огромным. Решение: ограничить количество снэпшотов в snapper config (TIMELINE_LIMIT_HOURLY, DAILY и т.д.).

Сравнение с FreeBSD

Loader. FreeBSD использует единый bootloader (loader, /boot/loader). Конфигурация: /boot/loader.conf (переменные, модули, tunables). Проще GRUB: нет генерации конфига, нет скриптов. Поддерживает UEFI и legacy BIOS, ZFS boot (включая encrypted ZFS с ядра 13+).

freebsd-update. Бинарные обновления base system (ядро + userland) как единого целого. freebsd-update fetch install — атомарное обновление. Для minor versions (13.2→13.3): freebsd-update -r 13.3-RELEASE upgrade. В Linux нет аналога — ядро и userland обновляются как отдельные пакеты.

bectl (Boot Environments). ZFS boot environments — штатный механизм FreeBSD: bectl create pre-upgrade && freebsd-update install. При неудаче: bectl activate pre-upgrade && reboot. Каждый BE — ZFS clone корневого dataset, стоимость O(1). В Linux аналог — Btrfs snapshots + grub-btrfs или rpm-ostree (Fedora CoreOS).

Отсутствие live patching. FreeBSD не имеет встроенного механизма live kernel patching. Обновление ядра всегда требует перезагрузки. Service jails (см. статью 6) с FreeBSD 14.2 частично смягчают проблему — сервисы в jail'ах могут быть перезапущены без перезагрузки ядра.

Источники


Связанные заметки

Из библиотеки института уносят только знания. Читателей здесь не считают: посещение не регистрируется, отметок в издании не остаётся, счётчиков нет ни у одного издания фонда.

Издание пополняется и пересверяется. Текст доступен на условиях CC BY-SA 4.0 — унесённое можно передавать дальше на тех же условиях.