Предлагаю вашему вниманию краткий пошаговый обзор процесса загрузки Linux. Он может отличаться для разных дистрибутивов Linux, но в целом справедлив для большинства современных.
Начнем с того, что процесс загрузки отличается в зависимости от того, какой режим был выбран в BIOS: Legacy (Compatibility Mode), Native UEFI. Некоторые материнские платы умеет комбинировать режимы, например, Dell.
Legacy boot
1. BIOS: базовая система ввода/вывода выполняет POST или самотестирование при включении питания, обнаружить и инициализировать аппаратные компоненты системы. Она же отвечает за аппаратные прерывания.
2. MBR: главная загрузочная запись расположена в первом секторе загрузочного диска, обычно /dev/hda или /dev/sda. Его размер составляет менее 512 байт, и он состоит из трех компонентов. Информация основного загрузчика в первых 446 байтах, информация таблицы разделов в следующих 64 байтах и проверка MBR в последних 2 байтах.
Это первый сектор любого диска с загрузочной таблицей, загружающий загрузчик GRUB2 в память.
3. GRUB2: GRUB начинает поиск в vmlinuz, который представляет собой сжатый образ ядра Linux, и загружает его в память, а затем извлекает содержимое образа initramfs. Обычно этот файл хранится в /boot
и путь к образу можно прочитать командой:
cat /proc/cmdline
Там же указывается и UUID корневой файловой системы, которую надо смонтировать.
4. ЯДРО: Ядро монтирует корневую файловую систему, как указано в параметре «root=» в grub.conf, затем выполняет программу /sbin/init
.
5. SYSTEMD: Systemd (заменил старый SysVinit) вызывает таргеты. В Linux есть так называемые режимы запуска, в первой системе инициализации они назывались «Уровни запуска» (runlevel). В SystemD они называются загрузочными таргетами, или boot targets. Таргеты systemd — это разные состояния, в которых может загружаться ваша система, сопоставимые с уровнями запуска System V. В отличие от уровней выполнения SysV, целевые модули имеют имена, а не нумеруются. Например, graphical.target аналогична уровню запуска SysV 5, многопользовательская с сетью и графической средой.
6. RUNLEVEL. Уровень запуска — это один из режимов, в котором будет работать Linux. На каждом уровне выполнения останавливается или запускается определенное количество служб, что дает пользователю контроль над поведением машины. Обычно существует семь уровней выполнения, пронумерованных от нуля до шести. В зависимости от настроек уровня запуска по умолчанию система будет выполнять программы из одного из следующих режимов:
Run Level | Mode | Action |
---|---|---|
0 | Halt | Выключение |
1 | Single-User Mode | Не настраивает сетевые интерфейсы, старт демонов, не-root вход |
2 | Multi-User Mode | Не настраивает сетевые интерфейсы, старт демонов |
3 | Multi-User Mode with Networking | Нормальный запуск в консольном режиме |
4 | Undefined | Не используется |
5 | X11 | Аналогичен 3 + графический интерфейс (X) |
6 | Reboot | Перезагрузка |
Systemd по умолчанию активирует модуль default.target при загрузке системы. Давайте проверим наш target по умолчанию:
systemctl get-default
Теперь давайте посмотрим на связь между runlevel и target:
- poweroff.target, уровень запуска 0
- rescue.target, уровень запуска 1
- multi-user.target, уровень запуска 3
- graphical.target, уровень запуска 5
- restart.target, запустите уровень 6
- emergency.target: уровень аварийного запуска
Например, таргет по умолчанию для рабочей станции с графическим интерфейсом пользователя (GUI) равно 5. Это значение соответствует уровню выполнения 5, который равен Graphical.target. Кроме того, runlevel для сервера равен 3, поскольку целью по умолчанию является multi-user.target.
Чтобы получить полный список активных таргетов, выполните команду:
systemctl list-units --type target
Чтобы поменять таргет по умолчанию, например, установить запуск оболочки консоли восстановления, выполните:
sudo systemctl set-default rescue.target
UEFI загрузка
Одним из ключевых различий между UEFI и BIOS является то, что UEFI поддерживает более современную схему разбиения lbcrf GPT, а встроенное ПО UEFI имеет возможность читать файлы из небольшой системы FAT. Это означает, что ваша конфигурация UEFI и двоичные файлы находятся в разделе GPT на вашем жестком диске. Это часто называют ESP (системный раздел EFI), обычно монтируемый в /efi
.
Будучи более гибким, UEFI устраняет необходимость использования загрузчика второго этапа, такого как GRUB. Часто, если вы устанавливаете одну операционную систему, например Ubuntu Desktop или Windows с включенным UEFI, вы можете обойтись без использования GRUB или любого другого промежуточного загрузчика. Если система установлена с поддержкой совместимости как BIOS, так и UEFI, в первых нескольких секторах жесткого диска будет иметься MBR-совместимый блок. Аналогично, если вам нужно выполнить загрузку с несколькими ОС или просто использовать загрузчик второго этапа по другим причинам, вы можете использовать GRUB или любой другой загрузчик.
Secure Boot
Безопасная загрузка — это стандарт безопасности. При включении компьютера с UEFI начинается процесс безопасной загрузки с прошивки материнской платы, которая проверяет криптографические подписи каждого из загрузочных файлов. Сюда входят драйверы прошивки UEFI (дополнительные ROM), приложения EFI и операционная система. После проверки компьютер загружается, и прошивка передает управление операционной системе.
Secure Boot использует 4 ключевые базы данных:
- База данных разрешенных подписей (db) — содержит список криптографических подписей, которые разрешено загружать во время процесса загрузки.
- База данных запрещенных подписей (dbx) — содержит список криптографических подписей, которые не разрешено загружать во время процесса загрузки.
- База данных ключей регистрации ключей (KEK) — содержит ключи обмена ключами, используемые для аутентификации других баз данных.
- База данных ключей платформы (PK) — содержит открытый ключ, который используется для проверки подписи любого загрузчика или прошивки, подписанной соответствующим закрытым ключом. Рекомендуемый ключ платформы для UEFI — RSA-2048.
MOK — это дополнительная база данных ключей, которой может управлять пользователь. Он не связан с ключом центра сертификации, который поставляется с shim. Они дают пользователю больше контроля над тем, какие модули можно загружать. Например, когда пользователь регистрирует MOK в системе, связанный с ним ключ добавляется в базу данных разрешенных подписей (db). Это означает, что любой двоичный файл, подписанный этим ключом, будет проверен прошивкой во время процесса загрузки.
Обычно они расположены в каталоге /var/lib/shim-signed/mok/
под именами MOK.der, MOK.pem или MOK.priv
.
Shim
При включении безопасной загрузки важно понимать, что такое shim («прокладка»). В контексте SecureBoot прокладка — это программа предварительного загрузчика, предназначенная для работы с прошивкой Secure Boot. Он позволяет загружать и выполнять загрузчики и модули ядра, если они не включены в базу данных безопасной загрузки. В Ubuntu загрузчик shim предустановлен и подписан центром сертификации Microsoft.
Secure Boot использует асимметричную криптографию, то есть используются открытый и закрытый ключи. Пара ключей может быть сгенерирована пользователем, а закрытый ключ используется для подписи всех программ, запуск которых разрешен, включая загрузчик GRUB. Прошивка UEFI будет использовать открытый ключ для проверки контрольных сумм и подписей программ перед их выполнением.
Переменные UEFI
Еще одна концепция — это переменные UEFI, которые хранятся в энергонезависимой памяти прошивки (NV-RAM). Эти переменные хранят различные данные, такие как настройки порядка загрузки, значения тайм-аута, настройки сети, сведения об устройстве хранения и настройки безопасной загрузки. Каждая переменная UEFI будет иметь собственный двоичный файл в папке /sys/firmware/efi/efivars/
.
В дальнейшем UEFI загрузка аналогична legacy загрузке: загружается и распаковывается ядро из раздела /boot
с тем лишь исключением, что проверяются подписи образов, модулей и драйверов. Утилита modinfo
позволяет посмотреть подписи модулей, который находятся в /lib/modules/
.
Системные драйверы, загружаемые ядром (initramfs) содержатся в /boot/initrd*