Uefi grub что это

Обновлено: 04.07.2024

BIOS - Basic Input Output System, это базовая система Ввода-Вывода, то есть набор программ зашитых в микросхему, использовалась ОС MSDOS, более современные ОС практически не используют BIOS.

За исключением процедуры POST - Инициализация и проверка работоспособности аппаратуры.

Если POST выполнен без ошибок, код BIOS начнёт поиск кода загрузчика ОС. Поиск выполняется на доступных и разрешённых в настройках носителях, код BIOS загрузит код загрузчика ОС в память и передаст ему управление.

  • 16-битный код, реальный режим(real-mode)
  • Отсутствие прямого доступа к 64-битному железу
  • Отсутствие единого стандарта
  • Сложность разработки.

2. UEFI на смену BIOS

Дословно Extensible Firmware Interface (EFI) - "расширяемый интерфейс прошивки"

EFI - интерфейс между операционной системой и микропрограммами, управляющими низкоуровневыми функциями оборудования, основное предназначение - корректно инициализировать оборудование при включении системы и передать управление загрузчику операционной системы.

EFI предназначен для замены BIOS, первый стандарт был разработан Intel, затем переработан и название заменено на UEFI (Universal).

Интерфейс, определённый спецификацией EFI, включает таблицы данных, содержащие информацию о платформе, загрузочные и runtime-сервисы, которые доступны для загрузчика операционной системы (ОС) и самой ОС.

Некоторые существующие расширения BIOS, типа ACPI и SMBIOS, также присутствуют в EFI, поскольку не требуют 16-разрядного runtime-интерфейса.

В дополнение к разнообразным службам и сервисам, EFI имеет оболочку - shell environment, для запуска программ, драйверов, создания исполняемых скриптов, для запуска утилит диагностики и обновления прошивок, работы с CD/DVD. Скрипты имеют расширение .nsh .

  • Отсутствие ограничений объема разделов и их количества
  • Увеличение скорости загрузки
  • Безопасность: возможность использования Secure Boot
  • Обратная совместимость с BIOS - CSM (Compatibility Support Mode)
  • Поддердка сетевой загрузки PXE
  • Менеджер загрузки

3. Загрузка в UEFI

Как происходит загрузка в UEFI:

Примечание: в дальнейшем рассматривается только схема разметки GPT GUID Partition Table.

однако, такие устройства как floppy, usb могут иметь FAT12 на ESP.

На партиции ESP, EFI по умолчанию ищет файл загручик:
\efi\boot\boot[название архитектуры].efi
например: \efi\boot\bootx64.efi и загружает его.

Далее уже работает сам загрузчик, by default это \efi\boot\bootx64.efi , он ищет корневую FS, на ней bootmanager или ядро, загружает их и передает им дальнейшее управление.

На самом деле, EFI BIOS, находит все ESP партиции, на всех носителях компьютера и на них файлы с расширением efi и если мы захотим загрузиться с какого-то иного носителя, второго диска или флешки, используя клавишу POP-UP меню загрузки BIOS, ну например F8 (у разных производителей могут разные функциональные клавиши), увидим все доступные носители с ESP и загрузчиками.

В отличие от BIOS, для UEFI используются другие ПЗУ, они дешевле, экономичней и имеют NVRAM в которой хранятся указатели на все найденные загрузчки .efi .

Структура ESP партиции выглядит следующим образом:

Примечание: Имена директорий Ubuntu, Debian, FreeBSD - всего лишь пример, можете использовать какие Вам угодно.

4. Windows on UEFI/GPT

Ничего необычно в установке Windows 7/8/10 на GPT из UEFI нет, ОС Windows ставится на диск с разметкой GPT только из UEFI.

  • настройка в UEFI BIOS -> загрузка UEFY Only
  • отключить Secure Boot
  • как уже было отмечено ранее, использовать официальный носитель с ОС
  • или выбрать правильный дистрибутив, если используете самодельные

Ниже показана структура ESP из Windows 7

  • ESP еще не создан.
  • На диске достаточно места для создания раздела емкостью 100 МБ.

  • MSR еще не создан.
  • На диске достаточно места для создания раздела емкостью 128 МБ.

Примечание: В Windows 8.x/10 ESP 350MB, а в Windows 10 MSR=0-16MB

Важно: чтобы из командной строки Windows (cmd.exe), можно было смонтировать Системный Раздел ESP, нужно отключить UAC, затем, перезагрузиться, после чего команда: отработает без проблем.

Отключение UAC и Windows Defender с командной строки.

выходим в командную строку Windows:

Пуск -> Выполнить -> cmd.exe -> Запустить от Администратора

Отключаем Windows Defender:

Отключаем UAC:

Теперь, если у нас административный account, можно не заботиться о разрешениях "от Администратора".

Снова выходим в командную строку и выполняем следующие действия для монтирования Системного раздела ESP - EFI System Partition:

Ниже показано содержимое ESP записанное при установке Windows 7:

В случае возникновения описанной выше проблемы, вместо одной команды придется выполнить несколько.

Выходим в командную строку и выполняем следующие действия для монтирования Системного раздела ESP - EFI System Partition:

  • выбираем диск командой sel
  • смотрим содержимое партиций

смотрим содержимое диска 1 (он пуст)

  • выбираем диск 0
  • партицию 1
  • назначаем букву для монтирования

Все, можем работать с Системным разделом EFI, он смонтирован как диск S:

Загрузчик Windows и BootManager.

Как было сказано ранее, в UEFI NVRAM содержатся настройки, переменные EFI, прописанные и обнаруженные загрузчики с расширением .efi, порядок загрузки и тд и тп.

Для настройки BootLoader и BootManager, Microsoft использует целую ветку в реестре, а работа с ней и управление, осуществляется командой bcdedit.

Посмотреть текущие настройки можно следующим образом:

вариант с лицензионной системы:

строка:
path \EFI\Microsoft\Boot\bootmgfw.efi
говорит об использовании оригинального EFI загрузчика от Microsoft.

  • \EFI\Boot\bootx64.efi
    и
  • \EFI\Microsoft\Boot\bootmgfw.efi

В случае хакерской активации через Slic, возможен такой загрузчик:
path \EFI\Microsoft\Boot\windslic.efi

Если установлен загрузчик rEFInd, path должен быть: path \EFI\REFIND\REFIND_X64.EFI

Изменить загрузчик из Windows, можно командой bcdedit: например:

5. Linux on UEFI/GPT

  • загрузка UEFY Only
  • отключить Secure Boot
  • если разметка отсутствует создает ESP и прописывает туда загрузчик efi
  • если разметка уже есть и ESP партиция в наличии, добавляет туда свой загрузчик и делает его default'ным

Примечание: В EFI/BIOS предлагается выбрать загрузку UEFI Only потому что с ней не будет проблем.

Это связано с реализацией UEFI/BIOS различными производителями.

  • - сначала найти ESP и попытаться загрузиться
  • - если ESP на устройствах отсутствуют, перейти к загрузке Legacy(BIOS)

Загрузка на некоторых материнских картах в случае выбора двух режимов; UEFI и затем Legacy может не найти реально существующий EFI-загрузчик на HDD.

Поэтому, лучше установить UEFY Only и установить ОС, а потом можно экспериментировать с настройками BIOS.

Кроме того, есть материнские карты отдельных производителей, у которых загрузчик ищется только в \EFI\Microsoft\Boot\.

Допустим мы ставили Linux на чистый диск из UEFI, посмотрим конфигурацию системы и загрузки GRUB2 + EFI: /dev/sda1 это /boot/efi ESP partition

Посмоотрим разметку диска (GPT):

рекомендую сохранять значение UUID для ESP (может пригодится для grub)

модуль efivars подгружается автоматически при установке из UEFI

благодаря ему, реализован очень полезный функционал, но будьте осторожны с содержимым, которое монтируется в /sys/firmware/efi!

Очень Важно: UEFI NVRAM доступна на запись от root'а, удаление данных в NVRAM, может стать катастрофой для компьютера!

Еще один важный и полезный инструмент, утилита efibootmgr позволяет решать проблемы загрузки.

посмотрим текущее состояние:

Все верхние примеры были на базе ОС Debian.

Работа c ESP в Linux

В нижнем примере это выглядит следующим образом:

содержимое ESP при единственной установленой ОС Debian

В Ubuntu отличаться будет лишь названием: /boot/efi/EFI/ubuntu/

  • Ubuntu и Debian имеют адаптированную утилиту fdisk для работы с GPT
  • или воспользоваться альтернативой: gdisk или parted

Примечание: Комментария и объяснения верхних команд не будет, как ими пользоваться можно прочитать в man

6. FreeBSD on UEFI/GPT

Установка FreeBSD из UEFI на чистый диск проходит без проблем, но если диск уже размечен как GPT и на нем есть ESP партиция, то встраиваться туда FreeBSD не умеет.

  • uname
  • camcontrol
  • gpart
  • mount
  • монтирование ESP и просмотр содержимого

Загрузка FreeBSD из UEFI коротко, четко и ясно описана в uefi(8)

UEFI firmware ищет загрузчик OS на EFI System Partition (ESP), если не установлен, по умолчанию грузит /efi/Boot/bootx64.efi. Это уже было описано.

  • boot1.efi читает /boot.config или /boot/config
  • затем ищет на ufs или zfs загрузчик loader.efi и загружает его
  • loader.efi загружает ядро - kernel

Создание USB/HDD UEFI Bootable в FreeBSD:

Просто. Далее можем развернуть систему руками, как обычно из /usr/freebsd-dist при загрузке с CD/DVD или Memstick.

Что из себя представляет /boot/boot1.efifat:

Немного смущает что разный размер:

Но ничего страшного, при ручной разметке я использовал /boot/boot1.efi и без автоскрипта для efi-shell startup.nsh

Как во FreeBSD создать свой /boot/boot1.efifat, например, размером 512K:

Верхнее, только в случае отсутствия других ОС на диске, для DUAL/TRIPLE Boot, ESP должна быть достаточного размера, в случае Windows не менее 100MB

Это легко посчитать установив один раз Windows+Linux+FreeBSD.

Как во FreeBSD создать EFI раздел: создать FAT32:

7. Dual/Triple/Multiboot Windows,Linux,FreeBSD on UEFI

  • Windows 7/8/10
    • использует существующую ESP при установке
    • делает собственый загрузчик default'ным, не интегрирует существующие ОС в меню загрузки
    • имеет утилиту управления загрузчиком: bcdedit
    • использует существующую ESP при установке
    • делает собственый загрузчик GRUB2-EFI default'ным, добавляет существующие ОС в загрузочное меню
    • имеет утилиту управления загрузчиком: efibootmgr
    • процедура установки не умеет использовать существующую ESP
    • не имеет утилит управления загрузчиком
    • имеет пакет(порт) grub2-efi для установки и настройки стороннего загрузочного менеджера
    • на один диск
    • на разные диски
    • в любом порядке
    • 1.Windows затем 2.FreeBSD
    • 1.Windows затем 2.Linux
    • 1.Linux затем 2.FreeBSD
    1. Windows
    2. FreeBSD
    3. Linux

    Следует отметить, верхние рекомендации, являются условными, потому что опираются на личное, субъективное мнение.

    • использовать ручную разметку диска: Manual
    • не создавать ESP партицию

    DualBoot Linux и Windows

    Как уже было сказано, при установке первой системой Windows, а затем Linux, проблем не будет.

    Не потребуется никаких дополнительных настроек, при установке Linux, будет установлен BootManager Grub2-EFI, grub2 найдет вторую систему и добавит в меню

    Меню GRUB2 в Debian будет выглядеть примерно:
    в Ubuntu

    Разберем что делать, если Windows была установлена позже и как создать меню загрузки в GRUB2.

    1. из Windows с помощью bcdedit
      или
    2. используя POP-UP меню BIOS выбрать загрузку Linux
    1. изменить порядок загрузки через efibootmgr
      имеем by default: BootOrder: 0005, где Boot0005* Windows Boot Manager меняем на debian
    2. создать меню загрузки Windows для GRUB2
      два варианта:
      1. достаточно выполнить утилиту os-prober (ее используют grub-probe и grub-mkconfig)
      2. или создать руками /etc/grub.d/40_custom

      UEFI DualBoot Windows и FreeBSD

      • Установщик FreeBSD не умеет интегрировать efi загрузчик в уже существующую ESP
      • В FreeBSD отсутствует утилита аналогичная efibootmgr
      1. порт sysutils/grub2-efi
      2. сторонний загрузчик rEFInd

      Установщик FreeBSD не умеет интегрировать свой загрузчик в уже существующую ESP и система не имеет утилиты манипуляции переменными EFI.

      Наименее затратный вариант, если FreeBSD будет установлена первой. При установке нужно проследить чтобы партиция ESP была размером не менее 100MB. В ином случае, разметить вручную Manual

      • разметку диска необходимо выполнить вручную Manual
      • ESP создавать НЕ НУЖНО! Должна быть только одна.
      • по завершению установки выйти в режим Live CD/USB и установить пакет sysutils/grub2-efi
      • или вместо grub2-efi установить из Windows загрузочный менеджер rEFInd

      Рассмотрим вариант установки FreeBSD позже остальных ОС с установкой и настройкой sysutils/grub2-efi.

      При установке выбираем Manual разметку диска, создаем как минимум freebsd-ufs для корня и freebsd-swap для swap, или устанавливаем zfs на пустую партицию.

      1. выполняем grub-mkconfig для создания конфигурации /boot/grub/grub.cfg
      2. удаляем секцию 10_kfreebsd из /boot/grub/grub.cfg - она создается НЕВЕРНО может мешать:
      3. создаем свою секцию 40_custom.dist меню загрузки Windows
        где root=(hd0,gpt1) это ESP партиция с efi-загрузчиком Windows
      • монтируем ESP
      • создаем директорию FreeBSD и копируем в нее загрузчик
      • установку и настройку rEFInd удобней выполнить из Windows, но можно из FreeBSD.
      • монтируем ESP используя команду mountvol
      • Скачиваем rEFInd
      • Разворачиваем архив в S:\EFI\refind
      • Удаляем все лишние из \EFI\refind
      • создаем конфиг refind.conf
      • настраиваем в нем нужные нам меню:
      • используя bcdedit устанавливаем refind как загрузчик by default
      • перезагружаемся и наслаждаемся меню rEFInd

      rEFInd имеет достаточное количество настроек и может быть использован как с текстовым меню или графическим с иконками и тд и тп. Используйте документацию и пример refind.conf-sample

      Теперь не составит труда настроить загрузку UEFI OS FreeBSD,Linux,Windows: Dual, Triple или MultiBoot.

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

      В этом руководстве мы выделим различные шаги, предпринятые ОС Linux с момента включения до момента входа в систему. Обратите внимание, что это руководство сфокусировано на загрузчике GRUB2 и systemd init, поскольку они используются в настоящее время подавляющим большинством современных дистрибутивов Linux. Но существуют и другие загрузчики, например, дистрибутивы на основе Arch Linux используют systemd-boot.


      Процесс загрузки состоит из следующих 4 шагов, которые мы обсудим более подробно:

      1. Инициализация системы: UEFI или BIOS (POST)
      2. Запуск загрузчика (GRUB2 или systemd-boot)
      3. Инициализация ядра
      4. Запуск systemd, родителя всех процессов

      1. Инициализация системы: UEFI или BIOS

      Инициализация системы под UEFI

      1. Система включена, выполняется самотестирование при включении (POST).
      2. После POST UEFI инициализирует оборудование, необходимое для загрузки (диск, контроллеры клавиатуры и т. д.).
      3. Прошивка считывает загрузочные записи в NVRAM, чтобы определить, какое приложение EFI запускать и откуда (например, с какого диска и раздела).
      • Загрузочной записью может быть просто диск. В этом случае микропрограмма ищет системный раздел EFI на этом диске и пытается найти приложение EFI в резервном загрузочном пути \EFI\BOOT\BOOTX64.EFI (BOOTIA32.EFI в системах с IA32 (32-разрядным) UEFI). Так работают загрузочные съёмные носители UEFI.
      1. Прошивка запускает приложение EFI.
      • Это может быть загрузчик или само ядро Arch, использующее EFISTUB.
      • Это может быть какое-то другое приложение EFI, такое как оболочка UEFI, или менеджер загрузки, например systemd-boot или rEFInd.

      Если включена безопасная загрузка, процесс загрузки будет проверять подлинность двоичного файла EFI по подписи.

      Инициализация системы под BIOS

      1. Система включена, выполняется самотестирование при включении (POST).
      2. После POST BIOS инициализирует оборудование, необходимое для загрузки (диск, контроллеры клавиатуры и т. д.).
      3. BIOS запускает первые 440 байтов (область кода начальной загрузки основной загрузочной записи) первого диска в порядке дисков BIOS.
      4. Затем первый этап загрузчика в загрузочном коде MBR запускает свой второй этап (если есть) из одного из следующих источников:
      • следующие секторы диска после MBR, то есть так называемый промежуток после MBR (только в таблице разделов MBR).
      • загрузочная запись тома раздела или диска без разделов (VBR).
      • загрузочный раздел BIOS (только GRUB в BIOS/GPT).
      1. Запускается фактический загрузчик.
      2. Затем загрузчик загружает операционную систему путём последовательной или прямой загрузки ядра операционной системы.

      Проверка целостности BIOS (POST)

      Процесс загрузки обычно инициализируется, когда пользователь нажимает кнопку включения — если ПК уже был выключен — или перезагружает систему с помощью графического интерфейса или командной строки.

      Когда система Linux включается, включается BIOS (базовая система ввода-вывода) и выполняет самотестирование при включении (POST). Это проверка целостности, которая выполняет множество диагностических проверок.

      В некоторых случаях раздаётся звуковой сигнал, особенно в случае отсутствия модуля RAM. Однако, если ожидаемое оборудование присутствует и функционирует должным образом, процесс загрузки переходит к следующему этапу.

      2. Загрузчик (GRUB2 или systemd-boot)


      Если компьютер запускает UEFI, то обычно она запускает приложение EFI, обычно располагающееся по пути \EFI\BOOT\BOOTX64.EFI (/boot/EFI/BOOT/BOOTX64.EFI) на загрузочном диске.

      Если это BIOS, то после завершения POST, BIOS проверяет MBR (главную загрузочную запись) на предмет загрузчика и информации о разделах диска.

      MBR — это 512-байтовый код, расположенный в первом секторе жёсткого диска, обычно это /dev/sda или /dev/hda, в зависимости от архитектуры вашего жёсткого диска. Обратите внимание, однако, что иногда MBR может находиться на Live USB или DVD-диске Linux.

      В Linux существует 2 основных типа загрузчиков: GRUB2 и systemd-boot. Загрузчик GRUB2 — распространён в дистрибутивах на основе Debian. Загрузчик systemd-boot применяется в Arch Linux и основанных на этой ОС дистрибутивах.

      Загрузчик GRUB2


      GRUB2 означает GRand Unified Bootloader version 2. Как только BIOS обнаруживает загрузчик grub2, он запускается и загружает его в основную память (RAM).

      Современный GRUB2 может работать и с UEFI (с помощью efibootmgr). В Arch Linux поддержка BIOS и UEFI собрана в один пакет grub. В Debian и производных дистрибутивах GRUB представлен двумя версиями:

      Меню grub2 позволяет вам делать несколько вещей. Оно позволяет вам выбрать версию ядра Linux, которую вы хотите использовать. Если вы несколько раз обновляли свою систему, вы можете увидеть в списке разные версии ядра. Кроме того, он даёт вам возможность редактировать некоторые параметры ядра, нажимая комбинацию клавиш клавиатуры.

      Кроме того, в настройке с двойной загрузкой, когда у вас есть несколько установок ОС, меню grub позволяет вам выбрать, в какую ОС загружаться. Файл конфигурации grub2 — это файл /boot/grub2/grub2.cfg. Основная цель GRUB — загрузить ядро Linux в основную память.

      Загрузчик systemd-boot

      systemd-boot (сокращенно sd-boot) — простой менеджер загрузки UEFI. Он предоставляет графическое меню для выбора записи для загрузки и редактор командной строки ядра. Systemd-boot поддерживает системы только с прошивкой UEFI.

      systemd-boot загружает информацию о загрузочной записи из системного раздела EFI (ESP), обычно монтируемого в /efi/, /boot/ или /boot/efi/ во время запуска ОС, а также из расширенного раздел загрузчика, если он существует (обычно монтируется в /boot/). Фрагменты файла конфигурации, ядра, initrds и другие образы EFI для загрузки обычно должны находиться на ESP или разделе расширенного загрузчика. Ядра Linux должны быть собраны с CONFIG_EFI_STUB, чтобы их можно было напрямую запускать как образ EFI. Во время загрузки systemd-boot автоматически собирает список загрузочных записей из следующих источников:

      • Загрузочные записи, определённые с помощью файлов описания спецификации загрузчика, расположенных в /loader/entries/ на ESP и в разделе расширенного загрузчика. Обычно они описывают образы ядра Linux со связанными образами initrd, но также могут описывать произвольные другие исполняемые файлы EFI.
      • Унифицированные образы ядра в соответствии со спецификацией загрузчика в виде исполняемых двоичных файлов EFI в /EFI/Linux/ на ESP и в разделе расширенного загрузчика.
      • Диспетчер загрузки Microsoft Windows EFI, если он установлен.
      • Диспетчер загрузки Apple MacOS X, если он установлен.
      • Бинарный файл EFI Shell, если он установлен
      • Перезагрузка в опцию настройки прошивки UEFI, если она поддерживается.

      systemd-boot поддерживает следующие функции:

      3. Инициализация ядра

      Ядро — это основа любой системы Linux. Он связывает оборудование ПК с базовыми процессами. Ядро контролирует все процессы в вашей системе Linux. После того как выбранное ядро Linux загружено загрузчиком, оно должно самораспаковаться из сжатой версии перед выполнением любой задачи. После самораспаковывания выбранное ядро монтирует корневую файловую систему и инициализирует программу /sbin/init, обычно называемую init.


      Init всегда запускается первой программой, и ей назначается ID процесса или PID 1. Это процесс init, который порождает различных демонов и монтирует все разделы файловых систем, указанные в файле /etc/fstab.

      Затем ядро монтирует начальный RAM-диск (initrd), который является временной корневой файловой системой, пока не будет смонтирована настоящая корневая файловая система. Все ядра находятся в каталоге /boot вместе с начальным образом RAM-диска.

      4. запуск Systemd

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

      Systemd использует файл /usr/lib/systemd/system/default.target для определения состояния или цели, в которую должна загружаться система Linux.

      • Для настольной рабочей станции (с графическим интерфейсом пользователя) целевое значение по умолчанию graphical.target.
      • Для сервера целью по умолчанию является multi-user.target.

      Вот виды целей systemd:

      • poweroff.target: выключение системы.
      • rescue.target: запускает сеанс спасательной оболочки.
      • multi-user.target: настраивает систему на неграфическую (консольную) многопользовательскую систему.
      • graphical.target: настройка системы на использование графического многопользовательского интерфейса с сетевыми службами.
      • reboot.target: перезагружает систему.

      Чтобы проверить текущую цель в вашей системе, выполните команду:


      Вы можете переключаться с одной цели на другую, выполнив на терминале следующую команду:

      Эта команда переводит систему в неграфическое состояние (после перезагрузки).

      А эта команда возвращает в загрузку в графический интерфейс:

      Процесс загрузки завершается, когда systemd загружает все демоны и устанавливает значение целевого уровня или уровня выполнения. Именно в этот момент вам будет предложено ввести имя пользователя и пароль, после чего вы получите доступ к своей системе Linux.

      Как устроена загрузка современных ОС? Как при установке системы настроить загрузку посредством UEFI, не утонув в руководствах и ничего не сломав?

      Я обещал "самое краткое руководство". Вот оно:

      1. Создаём на диске таблицу разделов GPT
      2. Создаём FAT32-раздел на пару сотен мегабайт
      3. Скачиваем из интернета любой UEFI-загрузчик
        (нам нужен сам загрузчик, это один бинарный файл!)
      4. Переименовываем и кладем этот файл на созданный раздел по адресу /EFI/Boot/bootx64.efi
      5. Создаём текстовый конфиг, кладем его там, где загрузчик ожидает его увидеть
        (настройка и местоположение конфига зависят от конкретной реализации загрузчика, эта информация доступна в интернете)
      6. После перезагрузки видим меню загрузчика
        (Если на диске установлена Windows 8 или 10 — с большой вероятностью это руководство сокращается до пунктов 3 — 5.)

      TL;DR не надо прописывать путь к загрузчику в новых загрузочных записях UEFI — надо файл загрузчика расположить по стандартному "пути по-умолчанию", где UEFI его найдет, и вместо загрузочного меню UEFI пользоваться меню загрузчика, которое гораздо проще и безопаснее настраивается

      Как делать не надо

      Есть, на самом-то деле, несколько способов настроить UEFI-загрузку. Я начну с описания других вариантов — чтобы было понятно, как (и почему) делать не надо. Если вы пришли за руководством — мотайте в самый низ.

      Не надо лезть в NVRAM и трогать efivars

      Наиболее "популярная" процедура установки загрузчика в систему такова: установщик ОС создаёт специальный раздел, на нём — структуру каталогов и размещает файлы загрузчика. После этого он с помощью особой утилиты (efibootmgr в linux, bcdedit в windows) взаимодействует с прошивкой UEFI-чипа, добавляя в неё загрузочную запись. В этой записи указывается путь к файлу загрузчика (начиная от корня файловой системы) и при необходимости — параметры. После этого в загрузочном меню компьютера появляется опция загрузки ОС. Для linux существует возможность вообще обойтись без загрузчика. В загрузочной записи указывается путь сразу к ядру вместе со всеми параметрами. Ядро должно быть скомпилировано с опцией EFISTUB (что давно является стандартом для большинства дистрибутивов), в этом случае оно содержит в себе заголовок "исполняемого файла EFI", позволяющий прошивке его запускать без внешнего загрузчика.

      При старте системы, когда пользователь выбирает нужную ему загрузочную запись, прошивка UEFI сперва ищет на прописанном в этой записи диске особый EFI-раздел, обращается к файловой системе на этом разделе (обязательно FAT или FAT32), и запускает загрузчик. Загрузчик считывает из файла настроек свой конфиг, и либо грузит ОС, либо предоставляет загрузочное меню. Ничего не замечаете? Да, у нас два загрузочных меню — одно на уровне прошивки чипа UEFI, другое — на уровне загрузчика. В реальности о существовании второго пользователи могут даже не догадываться — если в меню всего один пункт, загрузчик Windows начинает его грузить без лишних вопросов. Увидеть экран с этим меню можно, если поставить вторую копию Windows или просто криво её переустановить.

      Обычно для управления загрузочными записями руководства в интернете предлагают взаимодействовать с прошивкой UEFI. Есть аж пять основных вариантов, как это можно сделать: efibootmgr под linux, bcdedit в windows, какая-то софтина на "Маках", команда bcfg утилиты uefi shell (запускается из-под UEFI, "на голом железе" и без ОС, поскольку скомпилирована в том самом особом формате) и для особо качественных прошивок — графическими средствами UEFI (говоря популярным языком, "в настройках BIOS").

      За всеми вышенаписанными "многобуков" вы могли легко упустить такую мысль: пользователь, чтобы изменить настройки программной части (например, добавить параметр запуска ОС), вынужден перезаписывать flash-память микросхемы на плате. Есть ли тут подводные камни? О да! Windows иногда способна сделать из ноутбука кирпич, linux тоже, причём разными способами. Качество прошивок часто оставляет желать лучшего — стандарты UEFI либо реализованы криво, либо не реализованы вообще. По логике, прошивка обязана переживать полное удаление всех переменных efivars без последствий, не хранить в них критичных для себя данных и самостоятельно восстанавливать значения по-умолчанию — просто потому что пользователь имеет к ним доступ, и вероятность их полного удаления далека от нуля. Я лично в процессе экспериментов неоднократно (к счастью, обратимо) "кирпичил" свой Lenovo — из загрузочного меню исчезали все пункты, включая опцию "зайти в настройки".

      Работа с загрузочными записями UEFI — тоже не сахар. К примеру, утилита efibootmgr не имеет опции "редактировать существующую запись". Если ты хочешь немного изменить параметр ядра — ты удаляешь запись целиком и добавляешь её снова, уже измененную. При этом строка содержит в себе двойные и одинарные кавычки, а также прямые и обратные слеши в не особо очевидном порядке. Когда я наконец заставил эту магию работать — я сохранил её в виде bash-скриптов, которые до сих пор валяются у меня в корневой ФС:

      Не надо использовать GRUB

      Это чёртов мастодонт, 90% функциональности которого предназначено для дисков с MBR. Для настройки необходимо отредактировать ряд файлов, после чего выполнить команду генерации конфига. На выходе получается огромная малопонятная нормальному человеку простыня. В составе — гора исполняемых файлов. Ставится командой, которую просто так из головы не возьмешь — надо обязательно лезть в документацию

      Для сравнения — самый простенький UEFI-bootloader, который есть в составе пакета systemd, ставится командой

      Эта команда делает ровно две вещи: копирует исполняемый файл загрузчика на EFI-раздел и добавляет свою загрузочную запись в прошивку. А конфиг для неё занимает ровно СЕМЬ строчек.

      "Самое краткое руководство" — чуть более подробно

      Загрузочная запись нам не нужна — дело в том, что при выставлении в настройках BIOS загрузки с диска прошивка UEFI сначала ищет на нём EFI-раздел, а затем пытается исполнить файл по строго фиксированному адресу на этом разделе: /EFI/Boot/BOOTX64.EFI

      Что такое "EFI-раздел"? В теории, он должен иметь особый тип "EFI System" (ef00). На практике, годится первый раздел на GPT-диске, отформатированный в FAT32 и имеющий достаточно места, чтобы разместить загрузчик и вспомогательные файлы (если есть).

      Пункт 3: "Скачиваем из интернета любой UEFI-загрузчик". Что это значит? Загрузчик — это просто исполняемый файл определенного формата, к которому в комплекте идет конфиг. К примеру, если у вас есть под рукой установленный пакет с systemd — файл загрузчика можно найти по адресу /usr/lib/systemd/boot/efi/systemd-bootx64.efi, переименовать его в bootx64.efi и скопировать в /EFI/Boot/ на EFI-разделе. Нет под рукой systemd? Скачайте архив с сайта Archlinux. Или с репозитария Ubuntu. Или Debian. Есть под рукой система с Windows? Возьмите виндовый загрузчик оттуда, тоже сгодится )) Если сумеете настроить, я честно говоря не пробовал.

      Пункт 4: "Настроить конфиг". Как и обычная программа, когда загрузчик запускается — он ожидает найти по определенным путям файлы конфигурации. Обычно эту информацию легко найти в интернете. Для загрузчика systemd-boot нам необходимо в корне EFI-раздела создать каталог "loader", а в нём файл "loader.conf" с тремя строчками (привожу свои):

      Параметр editor отвечает за возможность отредактировать пункт загрузочного меню перед запуском.

      Рядом с loader.conf необходимо создать каталог entries — один файл в нём будет отвечать за одну загрузочную запись в boot-меню. У меня там один файл arch.conf с таким содержанием:

      Я не упомянул, но довольно очевидно — ядро и initramfs должны лежать в одной файловой системе с загрузчиком, то есть на EFI-разделе. Пути к ним в конфигах отсчитываются от корня этой ФС.

      Другие загрузчики

      systemd-boot очень простой и предоставляет спартанского вида чёрно-белое меню. Есть варианты красивей, если душа просит красоты.

      Clover. Позволяет выставлять нативное разрешение экрана, имеет поддержку мыши на экране загрузки, разные темы оформления. Дефолтная тема ужасна, конфиг в виде xml нечитаем, настроить не смог.

      Различные неочевидные последствия

      Вы можете легко попробовать эту схему в работе. Берёте USB-флешку, форматируете в таблицу разделов GPT, создаете FAT-раздел и копируете туда загрузчик. Комп сможет с неё стартовать.

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

      Продолжаем изучать GNU/Linux и готовиться к сертификации от Red Hat (RHCSA).

      Для работы какой-либо программы её нужно предварительно запустить. Какие-то программы мы запускаем сами, какие-то программы запускают другие программы. И при запуске компьютера есть определённая последовательность, какие программы что и зачем запускают. Процесс запуска операционной системы администратору нужно знать, потому что, во первых, это помогает выявить и решить какие-то проблемы, во вторых, это помогает какие-то проблемы предотвратить. Ну и в третьих помогает лучше понять работу операционной системы. Например, вспомните, мы с вами испортили запись в fstab, у нас система не прогрузилась, потом мы её исправили и всё заработало.

      Есть много сценариев запуска операционной системы, которые зависят от определенных условий. Например, мы с вами говорили про BIOS и UEFI, и тут, как минимум, уже два сценария запуска – с использованием MBR или раздела EFI system partition. Также мы с вами разбирали стандартные разделы, LVM, RAID – и это тоже добавляет варианты – используется ли для корня стандартные раздел или какой-то нестандартный, допустим, LVM. Ну и сегодня мы будем говорить о загрузчиках, и мало того что есть разные загрузчики, даже с учётом того, что мы будем разбирать только один загрузчик – grub, у него есть разные версии, от чего тоже появляются вариации. Но не будем усложнять, обо всём по порядку.

      Со всем вышесказанным мы знакомы, кроме загрузчика. Загрузчик – это программа, которая загружает операционную систему. Это особая программа, потому что она работает еще до того, как загрузилась операционная система, ядро и всякие другие программы. Тут можно понять, что у загрузчика должны быть свои, хотя бы минимальные драйвера для работы с компьютером – где-то он обращается к биосу, где-то напрямую к железу. При включении GNU/Linux-а мы видим такое окно – это такой интерфейс загрузчика Grub. Есть и другие загрузчики, но grub самый популярный, он стоит по дефолту на многих системах и чтобы не усложнять, мы будем говорить только о нём.

      И так, при включении у нас появляется окно grub, где мы можем выбрать нужную операционную систему. Если у нас на дисках установлены разные операционные системы мы сможем загрузить любую из них. К тому же тут также есть возможность загрузить одну и ту же операционку с разными версиями установленного ядра. Также отсюда мы можем повлиять на процесс загрузки – например, нажать “e” на нужной записи и изменить какие-то параметры. Но мы к этому еще придём. Плюс grub можно кастомизировать – поменять шрифт, рамки, цвета, поставить фон и всё такое. Чтобы лучше понять grub нам нужно хотя бы разок пройтись по сценарию запуска операционной системы.

      Возьмём самый простой сценарий BIOS – MBR – GRUB – корень на стандартном разделе. И так, вы нажали кнопку включения на компьютере, загрузился BIOS, какие-то свои задачи выполнил, а дальше обращается к порядку загрузки – диски, флешки, сеть и всё такое. Предположим, у нас на первом месте жесткий диск. BIOS загружает первый сектор - 512 байт этого диска, то есть MBR. Как мы помним, у нас в MBR есть загрузчик и таблица разделов. Для загрузчика выделено 446 байт – это очень маленький объём, куда невозможно поместить полностью grub – поэтому здесь лежит программа, в которой прописан блочный путь к основной части grub-а. Блочный – потому что поддержку файловой системы в такой маленький объём не запихнуть. Этот шаг, когда загружается маленькая часть grub из MBR называется этапом 1. В случае со старым железом BIOS мог видеть только первые 1024 цилиндра жесткого диска, т.е. примерно первые 500 мегабайт, а если основная часть grub-а находилась в другом месте – то не получилось бы его загрузить. Поэтому для таких случаев существовал этап 1.5, когда загружалась чуть большая часть grub-а, расположенная в первых 62 секторах диска, где лежали драйвера для файловых систем. Загрузив их grub мог уже полноценно найти и загрузить основную свою часть, которая лежит в директории /boot/grub – т.е. приступить к этапу 2.

      Grub, загрузив свою основную часть, обращается к файлу /boot/grub/grub.cfg и берёт оттуда записи, что и как грузить. Если говорить про Linux, то задача grub – загрузить ядро и передать ему нужные параметры. Эти параметры видны в строчке linux – собственно, файл vmlinuz, который мы видели в директории /boot, файловая система, где лежит корень (root=..) и всякие дополнительные опции – например, rhgb – чтобы отображать анимацию, пока грузится операционная система и quiet – чтобы скрыть подробный вывод при запуске. Давайте, для примера, сотрём последние две опции (rhgb quiet) и нажмём ctrl+x, чтобы загрузиться. Как видите, теперь при загрузке отображается куча информации, что может быть полезно, если по какой-то причине система не грузится и мы пытаемся найти причину. Но после перезагрузки эти опции опять будут на месте, потому что мы их стёрли в текущей сессии, а не в конфиг файле.

      Окей, grub запустил ядро. Что дальше? Ядро начинает запускаться, находить устройства и загружать драйвера. Но для этого ядру нужны модули. Вспомните про модульность ядра – у ядра есть встроенные модули и загружаемые. Встроенные уже в самом файле vmlinuz, а загружаемые лежат в директории /lib/modules/. Ядро загрузит то что сможет, используя встроенные модули, а дальше ядру нужен доступ в директорию /lib/modules. Для этого ядро должно примонтировать корень. Только вот такой нюанс – для того, чтобы примонтировать корень, ядру нужны модули – как минимум, модуль scsi и модуль файловой системы. Давайте посмотрим список встроенных модулей (cat /lib/modules/$(uname -r)/modules.builtin | grep -e scsi -e ext4 ). Как видите, тут есть модули scsi, но нет модуля ext4. То есть ядро просто не сможет примонтировать корень, чтобы взять оттуда модули. При этом, чтобы эти модули были, ему нужно примонтировать корень.

      Можно было бы встроить в ядро все нужные модули, но это сделает ядро значительно тяжелее, файловых систем много, да и если брать LVM и прочее.. ну в общем не выход. Эта проблема решается по другому. В grub под строкой с linux есть еще одна строка – initrd – initial ram disk. Как видите, она указывает на файл. Этот файл – ram disk – временный образ корня, который специально предназначен для решения указанной проблемы. При загрузке grub монтирует этот файл в качестве корня и ядро может с ним работать. Собственно здесь оно находит все нужные драйвера для того, чтобы загрузить настоящий корень, после чего ядро переключается на основной корень. Этот временный корень не содержит все файлы, а только необходимый минимум, какие-то драйвера файловых систем и т.п., чтобы можно было перейти на нужный корень. Но в каких-то дистрибутивах сюда включены чуть ли не все драйвера и некоторые программы. И если у вас какие-то проблемы с корнем, не получается монтировать, или, например, вы хотите сделать fsck корня, то используя этот временный корень вы можете провести какие-то работы.

      Но на самом деле, если присмотреться, файл называется не initrd, а initramfs – initial ram file system. Initramfs пришел на замену initrd, так как у initrd есть определённые недостатки. Например, initrd был файлом образом блочного устройства, внутри которого была файловая система, а значит ядру для работы с ним нужен был хотя бы один встроенный модуль файловой системы. Initramfs это больше архив, который распаковывается в виртуальную файловую систему tmpfs. А tmpfs является частью ядра, предназначенной для всяких файловых систем, работающих в оперативке. Так вот, когда ядро видит initramfs, оно берёт оттуда нужные модули, а также запускает программу, ну или просто скрипт с названием init. Она может выполнять какие-то команды, если этого захотели разработчики дистрибутива, и в итоге монтирует настоящий корень и переключается на него. Есть небольшие отличия в работе между initrd и initramfs, но такие подробности нам сейчас не нужны.

      Так вот, после всей этой инициализации, когда ядро взяло нужные модули из initramfs, init запускает программу /sbin/init в настоящем корне, которая стартует систему инициализации. Система инициализации – это отдельная тема, которую будем разбирать в следующий раз. Пока что мы разобрали только один сценарий BIOS – MBR – GRUB – стандартный раздел. Давайте вкратце пройдёмся по нему – BIOS грузит загрузчик из MBR на 446 байт, это первый этап загрузки GRUB-а. Дальше GRUB грузит свой второй этап, ссылаясь на /boot/grub. Полностью загруженный GRUB видит в конфигах путь к ядру и initramfs, загружает ядро и initramfs в оперативку, ядро подгружает нужные модули благодаря initramfs, запускает init, который в итоге переключается на реальный корень и запускает программу /sbin/init – то есть систему инициализации. В других сценариях в целом многое будет схоже, но отличия всё же есть, давайте их разберём.

      Заменим стандартный раздел на LVM. Допустим, корень у нас в LVM. Чтобы grub мог загрузить ядро и initramfs, ему нужен доступ в директорию /boot, но если они находятся на LVM разделе, grub не сможет их увидеть. В таких случаях директорию /boot выносили на отдельный стандартный раздел. Благодаря чему grub мог загрузить ядро и initramfs со стандартного раздела, а дальше ядро находило в initramfs модули для LVM и могло примонтировать реальный корень.

      Но так было раньше, со старой версией Grub, которая сейчас называется grub-legacy. Современная версия grub называется grub2 и она поддерживает LVM, благодаря чему нет необходимости выносить /boot на отдельный раздел.

      Если заменить BIOS на UEFI, то отпадает необходимость в загрузчике в MBR. При включении UEFI ищет раздел EFI system parititon и загружает оттуда bootx64.efi или grubx64.efi . А это запускает grub, который обращается к файловой системе, где находится директория /boot/grub и дальше всё как мы говорили.

      Давайте посмотрим, как всё организовано на нашей виртуалке. Virtualbox для гостевых машин использует BIOS. Таблица разделов у нас dos, т.е. используется MBR (sudo fdisk -l /dev/sda). Ну и если посмотреть файловые системы (mount | gred sda), можно увидеть, что boot вынесен в отдельный раздел, а для корня используется LVM (mount | grep “ / “). При этом grub у нас второй версии (ls /boot/grub2). Если вы слушали внимательно, вы помните, что grub2 поддерживает LVM, и выносить /boot на стандартный раздел не нужно. Но официально RedHat рекомендует держать /boot всё таки на стандартном разделе. Объяснения почему я не нашел, но, предполагаю, что дело в решении проблем. Если у вас возникнут проблемы с LVM, вы не сможете загрузить даже ядро с initramfs, потому что они лежат на логическом разделе, вам придётся использовать live-cd. Стандартный раздел для /boot позволит вам прогрузить хотя бы ядро с initramfs. Хотя, возможно, есть и другие причины, но о причинах в документации ничего не сказано.

      Ну и напоследок, давайте немного подредактируем grub. Хотя сам конфиг это /boot/grub2/grub.cfg (sudo cat /boot/grub2/grub.cfg ), вручную редактировать этот файл не стоит, он будет перезаписываться при обновлениях. Чтобы наши изменения оставались даже после обновления, нужно редактировать файл /etc/default/grub (sudo nano /etc/default/grub). Например, уберём rhgb и quiet в строчке GRUB_CMDLINE_LINUX и сохраним. После этого нужно обновить конфиг файл grub-а. Сначала убеждаемся, что всё нормально, просто запускаем команду grub2-mkconfig. Если всё нормально, то мы увидим будущий конфиг. Затем перенаправляем вывод этой команды в файл /boot/grub2/grub.cfg (sudo grub2-mkconfig | sudo tee /boot/grub2/grub.cfg ). Ну и для проверки можем перезагрузиться. Как видите, наши изменения сработали.

      Ну и если говорить про initramfs, стоит упомянуть возможность добавлять в него определённые модули. Пример из практики – у вас есть виртуальная машина на гипервизоре ESXi, это такой коммерческий гипервизор от компании VMWare. И вам нужно перенести виртуальную машину на гипервизор KVM – свободный гипервизор, активно используемый в Linux-ах. Если вы просто перенесёте файлы, скорее всего у вас виртуальная машина просто не запустится. Причина – ядро виртуалки при запуске просто не увидит корень, у вас не будет дисков sda, sdb и т.д. Чтобы ядро увидело диски, ему нужны будут другие драйвера scsi – virtio. Но они не встроены ни в ядро (cat /lib/modules/$(uname -r)/modules.builtin | grep virtio), ни в initramfs (sudo lsinitrd /boot/initramfs-$(uname -r).img | grep virtio). Список модулей в initramfs можно увидеть с помощью команды lsinitrd /boot/initramfs-$(uname -r).img . Ну и чтобы добавить эти модули в initramfs, нужно создать файл в /etc/dracut.conf.d/ c каким-то названием .conf и списком необходимых модулей (add_drivers+=” virtio_blk virtio_scsi “ ). Ну и сгененировать новый образ initramfs (sudo dracut -f -v /boot/initramfs-$(uname -r).img $(uname -r) ). После чего можем убедиться, что новые модули будут в initramfs (sudo lsinitrd /boot/initramfs-$(uname -r).img | grep virtio).

      Подводя итоги. Сегодня мы с вами разобрали, как операционная система запускается – куда обращаются BIOS и UEFI, что такое загрузчик и какова его роль, зачем нужна директория /boot, почему ядро и initramfs находятся в этой директории, ну и что такое initramfs.

      Читайте также: