@ Карта сайта News Автора!

Bog BOS: hardware:  EFI, UEFI и PI

Последнее изменение файла: 2017.11.24
Скопировано с www.bog.pp.ru: 2017.11.25

Bog BOS: hardware: EFI, UEFI и PI

Unified Extensible Firmware Interface (UEFI) - спецификация интерфейса между ОС и прошивкой вычислительной платформы, пришедшая на смену интерфейсу BIOS (real mode, 16 бит, 1MB на всех и 192 КиБ на драйвер карты расширения). Большинство реализаций поддерживают интерфейсы BIOS для совместимости. Первоначально называлась EFI (1999) и предназначалась для Intel/HP Itanium, затем права EFI 1.10 были переданы Unified EFI Forum и в 2006 году появилась UEFI 2.0 (слово EFI осталась в именах файлов, библиотек и утилит).

Спецификация UEFI описывает состояние после завершения инициализации платформы и определяет интерфейс между прошивкой и приложениями UEFI - внешними программами, используемыми, в частности, для загрузки ОС. Кроме приложений UEFI определяются драйверы UEFI - вспомогательные программы, реализующие до загрузки ОС определённые в спецификации протоколы. Центральной частью UEFI является менеджер загрузки, который (после инициализации платформы) загружает в определённом порядке драйверы и приложения до тех пор, пока не окажется запущенной ОС. Предоставляемые UEFI сервисы делятся на сервисы периода загрузки (недоступны после запуска ОС) и очень небольшой набор сервисов периода выполнения (доступны всегда). В комплекте с UEFI разработаны спецификации инициализации платформы PI (Platform Initialization Specification), ранее называлась Intel Framework, формат пакетов UEFI/PI и UEFI Shell. Имеется открытая реализация верхней части PI/UEFI - Tianocore (EDK - EFI Development Kit, далее EDK2, UDK2010 и т.д.).

В настоящий момент поддерживает следующие платформы (только little-endian, 32 или 64-битные): IA-32, IA-64, x64, AArch32, AArch64, RISC-V; существуют проекты для добавления POWERPC64, OpenPOWER и MIPS. Разрядность UEFI прошивки должна соответствовать разрядности UEFI приложений (загрузчики и пр.). На практике прошивка платформы x86-64 будет 64-битной (кроме старых Atom-ов), проверить можно в /sys/firmware/efi/fw_platform_size. Дополнительно определяется архитектура виртуальной машины EBC (EFI Byte Code), которая может быть использована для написания драйверов и приложений. Предполагается возможность написания драйверов и приложений на языках высокого уровня, интерфейсы описываются в стиле языка C.

Декларируется совместимость со "старой жизнью" - возможность загрузки ОС, совместимых с BIOS или UEFI, на одной и той же платформе с одного и того же носителя, а также возможность для разработчиков карт расширения поддерживать одновременно UEFI драйвера и BIOS-совместимые ROM.

В качестве кодировки символов используется UCS-2 (конец строки - 0x0000). Для нумерации объектов (протокол, драйвер, пространство имён переменных, раздел и т.д.) повсеместно используется GUID (Globally Unique IDentifier) длиной 128-бит, предполагается, что случайный выбор GUID в пространстве такой мощности обеспечит уникальность без согласования между разработчиками в центральной конторе.

Текущая (2017 год) версия 2.7, но в самой свежей прошивке от Intel стоит UEFI версии 2.4, поэтому для ориентировки в возможностях реализации важно знать, что было добавлено в очередной версии:

Формат исполняемых образов UEFI

Заголовок файлов UEFI исполняемых образов (драйверы, приложения) д.б. оформлен в формате подмножества PE32+ (PE/COFF с 64-битным расширением, Microsoft Portable Executable and Common Object File Format), в котором указывается архитектура (м.б. EBC) и тип файла (pre-OS agent):

Образы могут храниться на материнской плате (System ROM), карте расширения (Expansion ROM, PCI ROM), устройстве хранения (media), загрузочном сетевом сервере. Определён формат архивов (FirmwareVolume, FV), содержащих образы, - файловая система FFS.

Инициализация платформы

Platform Initialization (PI) Specification - стандарт на процедуру инициализации, реализация базы, на которой зиждется UEFI, делится на фазы:

Предусмотрены следующие программные абстракции (Architectural Protocol): безопасность, ЦП, метроном, таймер, BDS (Boot Device Select), сторожевой таймер, переменные UEFI, запись переменных UEFI, сброс, монотонный счётчик, часы реального времени, коды состояния, runtime (обеспечивает переход сервисов из физического режима памяти к виртуальному). Драйверы обеспечивают сервисы для других модулей с помощью протоколов (протокол определяется в спецификации UEFI); могут быть написаны на EBC или с использованием родной системы команд.

Драйверы делятся на:

Legacy ROM карты расширения PCI (PCIe) в основном содержат 16-битный код в режиме real (адресация 1 нижнего МиБ, 128 KiB для Leagacy ROM - 0xC0000-0xDFFFF) для процессора архитектуры IA-32. И?

Обработка событий (событие м.б. в 2 состояниях - ожидание и сигнальное):

Прерываний от оборудования нет (кроме single-timer interrupt?), только опрос (polling). Извещение с высоким приоритетом прерывает выполнение извещения с низким приоритетом. Приоритет TPL_HIGH_LEVEL блокирует даже прерывания от таймера. Типы событий:

После PI выполняется фаза выбора загрузочного устройства (BDS, Boot Device Select), загрузка UEFI приложений и выполнение ОС.

CSM (Compatibility Support Module) обеспечивает совместимость с BIOS, включает CSM16 (обеспечивается писателем BIOS) и интерфейс с PI.

Разработка приложений под EFI возможна с использованием пакетов edk2-tools (edk2-tools-doc, edk2-tools-python) от UEFI Forum или на базе более старой версия от Intel - gnu-efi (gnu-efi-utils, gnu-efi-devel).

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

Общий взгляд на UEFI

Спецификация UEFI описывает состояние после завершения инициализации и включает следующие понятия:

  • абстрактные протоколы доступа к шинам и устройствам на шинах PCI, SCSI, iSCSI, USB - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL (работа с шинами PCI, один PCI Host Bus Controller (общее пространство адресов IO и MMIO) может иметь несколько корней, PCI сегмент - набор шин с общим пространством конфигурации - может обслуживаться одним PCI Root Bridges или несколькими, PCI Root Bridges может обслуживать локальную PCI или целый сегмент PCI), EFI_PCI_IO_PROTOCOL (работа с IO, MMIO и памятью конфигурации PCI устройств; в ROM - копируется в память - может располагаться UEFI драйвер), EFI_ATA_PASS_THRU_PROTOCOL (передача ATA команд, в т.ч. для логическим устройств RAID контроллера, опционально неблокирующий режим), EFI_SCSI_IO_PROTOCOL (передача SCSI команд), EFI_EXT_SCSI_PASS_THRU_PROTOCOL (передача расширенных SCSI команд, например, для ATAPI), EFI_ISCSI_INITIATOR_NAME_PROTOCOL, EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL (передача NVM Express команд), в т.ч. для логическим устройств RAID контроллера, опционально неблокирующий режим, EFI_USB_IO_PROTOCOL, EFI_USB2_HC_PROTOCOL, EFI_SD_MMC_PASS_THRU_PROTOCOL (передача SD/eMMC команд), EFI_NVDIMM_LABEL_PROTOCOL (хранилише описаний адресного пространства), EFI_UFS_DEVICE_CONFIG_PROTOCOL (Universal Flash Storage)
  • байтовый поток EFI_SERIAL_IO_PROTOCOL (параметры: глубина буфера, скорость, чётность, количество бит данных и пр.; управление RTS и DTR, петля, контроль потока; состояния CTS, DSR, CD и RI)
  • протоколы поддержки графики - EFI_SIMPLE_POINTER_PROTOCOL (3 координаты и 2 кнопки) и EFI_ABSOLUTE_POINTER_PROTOCOL, EFI_GRAPHICS_OUTPUT_PROTOCOL (GOP, для замены VGA BIOS, чтение и установка режима, Blt - Block Transfer, 32 бита на пиксель, 800x600 или 640x480, поддержка нескольких устройств вывода), EFI_EDID_DISCOVERED_PROTOCOL, EFI_EDID_ACTIVE_PROTOCOL, EFI_EDID_OVERRIDE_PROTOCOL
  • обновление прошивки - EFI_FIRMWARE_MANAGEMENT_PROTOCOL (подписанная изменённая прошивка кладётся в область ожидания обновлений, после сброса специальный модуль проверяет подпись заявок в области ожиданий и удовлетворяет прошедшие контроль заявки)
  • сетевые протоколы загрузки (SNP, PXE, BIS, HTTP) - EFI_SIMPLE_NETWORK_PROTOCOL (абстракция пакетной передачи), EFI_PXE_BASE_CODE_PROTOCOL, EFI_BIS_PROTOCOL, EFI_HTTP_SERVICE_BINDING_PROTOCOL, EFI_HTTP_PROTOCOL, EFI_HTTP_UTILITIES_PROTOCOL
  • MNP (EFI_MANAGED_NETWORK_PROTOCOL) - асинхронный сетевой пакетный сервис - и EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL (поиск сетевого устройства)
  • UNDI (Universal Network Driver Interface) - EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
  • управление сетью (включая VLAN, Wi-Fi, EAP, Bluetooth) - EFI_VLAN_CONFIG_PROTOCOL; EFI_ADAPTER_INFORMATION_PROTOCOL, EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL; EFI_EAP_PROTOCOL, EFI_EAP_CONFIGURATION_PROTOCOL, EFI_EAP_MANAGEMENT2_PROTOCOL, EFI_SUPPLICANT_PROTOCOL, EFI_EAP_CONFIGURATION_PROTOCOL; EFI_BLUETOOTH_HC_PROTOCOL, EFI_BLUETOOTH_IO_PROTOCOL, EFI_BLUETOOTH_CONFIG_PROTOCOL, EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL, EFI_BLUETOOTH_LE_CONFIG_PROTOCOL
  • сетевые протоколы (IP, TCP, UDP, IPsec, TFTP, TLS, ARP, DHCP, DNS, REST) - EFI_ARP_SERVICE_BINDING_PROTOCOL, EFI_ARP_PROTOCOL, EFI_DHCP4_SERVICE_BINDING_PROTOCOL, EFI_DHCP4_PROTOCOL, EFI_TCP4_SERVICE_BINDING_PROTOCOL, EFI_TCP4_PROTOCOL, EFI_IP4_SERVICE_BINDING_PROTOCOL, EFI_IP4_PROTOCOL, EFI_IP4_CONFIG_PROTOCOL, EFI_IP4_CONFIG2_PROTOCOL, EFI_UDP4_SERVICE_BINDING_PROTOCOL, EFI_UDP4_PROTOCOL и аналоги для IPv6; EFI_TLS_SERVICE_BINDING_PROTOCOL, EFI_TLS_PROTOCOL, EFI_TLS_CONFIGURATION_PROTOCOL; EFI_IPSEC_CONFIG_PROTOCOL, EFI_IPSEC2_PROTOCOL; EFI_MTFTP4_SERVICE_BINDING_PROTOCOL, EFI_MTFTP4_PROTOCOL; EFI_DNS4_SERVICE_BINDING_PROTOCOL, EFI_DNS4_PROTOCOL, EFI_DNS6_SERVICE_BINDING_PROTOCOL, EFI_DNS6_PROTOCOL; EFI_REST_PROTOCOL
  • безопасная загрузка и цифровая подпись драйверов и приложений
  • интерфейс пользователя (HII), описывается в виде форм и строк в UCS-2 (базы строк, шрифтов и изображений), драйвер при инициализации регистрирует свою часть в базе HII, а затем реагирует на события конфигурации - EFI_HII_DATABASE_PROTOCOL, EFI_HII_STRING_PROTOCOL, EFI_HII_CONFIG_ROUTING_PROTOCOL, EFI_HII_CONFIG_ACCESS_PROTOCOL, EFI_HII_FONT_PROTOCOL.
  • идентификация пользователя по паролю, смарт-картам, биометрическим устройствам и т.д. с раздачей прав (например, только администратор может загрузить нестандартное приложение), для запроса используется HII - EFI_AUTHENTICATION_INFO_PROTOCOL
  • протоколы безопасности (хеширование, управление ключами, датчик случайных чисел, Smart Card) - EFI_HASH_PROTOCOL, EFI_HASH_SERVICE_BINDING_PROTOCOL; EFI_RNG_PROTOCOL
  • EFI_RAM_DISK_PROTOCOL (регистрация RAM диска)
  • протоколы доступа к таблицам ACPI
  • формат записей об аппаратных ошибках
  • UEFI shell
  • Протокол локации устройства (Device Path)

    Device Path - протокол локации устройства (двоичный) EFI_DEVICE_PATH_PROTOCOL, разрабатывался с учётом ACPI. Имеются протоколы преобразования в текстовый формат EFI_DEVICE_PATH_TO_TEXT_PROTOCOL и обратно EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL. Путь (список путей) состоит из неограниченной последовательности узлов, в текстовом формате узлы представляются в виде функции со списком аргументов через запятую, узлы разделяются символом "/".

    Узлы бывают следующих типов (если тип нераспознан, то "Path(тип,подтип,данные)"):

    1. HardwarePath(подтип,данные) - физическое подключение (MMIO, IO), шина предоставляет ресурсы в домене когерентности (пространство памяти, IO, пространство конфигурации PCI), подтипы:
      1. Pci - функция и устройство в пространстве конфигурации PCI, шина не указывается т.к. может меняться, перед PCI узлом в цепочке должен быть ACPI узел, определяющий корень PCI шины; например: "PciRoot(0x0)/Pci(0x1f,0x2)/Sata(1,0,0)" или "PciRoot(0x0)/Pci(0x1c,0x4)/Pci(0x0,0x0)/MAC(a4bf010603c4,1)"
      2. PcCard - номер функции (нумеруются с 0)
      3. MemoryMapped - тип (MMIO, IO Port и т.д.), начало, конец
      4. VenHW - GUID поставщика, данные
      5. Ctrl - номер контроллера
      6. BMC - тип интерфейса (1 - KCS, 2 - SMIC, 3 - Block Transfer), базовый адрес BMC в памяти или IO
    2. AcpiPath(подтип,данные) - ACPI устройство, идентификаторы PnP оборудования (_HID) и уникальные идентификаторы (_UID, серийный номер), используется при отсутствии возможности Hardware Device Path (корень PCI шины), подтипы:
      1. Acpi - указывается _HID и _UID, например: "PciRoot(0)/Pci(0x1f,0)/ACPI(PNP0501,0)", где _HID
        • PNP0A03 - PciRoot(идентификатор)
        • PNP0A08 - PcieRoot(идентификатор)
        • PNP0301 - Keyboard(идентификатор) - клавиатура
        • PNP0501 - Serial(идентификатор) - последовательный порт (_UID от 0 до 3 - номер порта)
        • PNP0401 - ParallelPort(идентификатор) - параллельный порт (_UID от 0 до 3 - номер порта)
      2. AcpiEx - указывается _HID, _UID и _CID в двоичном или текстовом (ASCII) формате
      3. AcpiAdr - атрибуты видеовывода - указывается _ADR (таблица B-2 ACPI 3.0); также используется для NVDIMM (NFIT, ACPI 6.0)
    3. Messaging Device Path - Msg(подтип,данные) - не координатные методы поиска устройств, шина потребляет ресурсы домена когерентности и предоставляет ресурсы вне домена когерентности
      1. Ata(контроллер,устройство,LUN) - ATAPI - указывается первичный/вторичный, главный/подчинённый
      2. SCSI - указывается номер исполнителя и LUN (маловато будет)
      3. Fibre - FibreChannel - указывается WWN и LUN
      4. I1394 - Firewire (IEEE 1394) - указывается GUID в терминах IEEE 1394
      5. USB - указывается номер порта и номер интерфейса, например: "PciRoot(0x0)/Pci(0x1d,0x0)/USB(1,0)/USB(3,0)"
      6. I2O - указывается целевой идентификатор (TID)
      7. InfiniBand - указывается GID удалённого порта фабрики, постоянный адрес удалённого устройства и др.
      8. VenMsg - указывается GUID поставщика и пр. параметры, определены GUID для PC-ANSI (VenPcAnsi()), VT-100 (VenVt100()), VT-100+ (VenVt100Plus()), VT-UTF8 (VenUtf8()), UartFlowCtrl (0 - None, 1 - Hardware, 2 - XonXoff); должны стоять в конце цепочки узлов, например: "PciRoot(0)/Pci(0x1f,0)/ACPI(PNP0501,0)/UART(115200,N,8,1)/UartFlowCtrl(2)/DebugPort()"; сюда же почему-то попал SAS с GUID d487ddb4-008b-11d9-afdc-001083ffca4d (есть и отдельный подтип для SAS) - указывается SAS адрес исполнителя, LUN, топология (внутренние SAS по SSP и SATA, внещние SAS или SATA черех экспандер), порт исполнителя, например: "PciRoot(0)/PCI(1,0)/Sas(0x31000004CF13F6BD, 0, SATA)"; сложности с двухпортовыми устройствами
      9. MAC адрес - указывается MAC адрес и тип сети, напимер: "PciRoot(0x0)/Pci(0x1c,0x4)/Pci(0x0,0x0)/MAC(a4bf010603c4,1)"
      10. IPv4 - указывается местный адрес, удалённый адрес, локальный порт, удалённый порт, сетевой протокол (UDP/TCP), адрес получен по DHCP или статически, адрес шлюза, маска подсети, например: "PciRoot(0)/Pci(19,0)/Mac(001320F5FA77,0x01)/IPv4(192.168.0.100,TCP,Static,192.168.0.1)"
      11. IPv6 - указывается местный адрес, удалённый адрес, локальный порт, удалённый порт, сетевой протокол (UDP/TCP), адрес получен статически или с помощью автоматической конфигурации, длина префикса, адрес шлюза
      12. UART - указываются параметры последовательного порта, например: "PciRoot(0)/Pci(0x1f,0)/ACPI(PNP0501,0)/UART(115200,N,8,1)
      13. UsbClass - указывается идентификатор изготовителя, идентификатор продукта, класс, подкласс, код протокола; может использоваться в сокращённой форме (без указания начала последовательности узлов и/или с использованием шаблона 0xFF в любых позициях, например (любая клавиатура): "UsbHID()")
      14. UsbWwid - указывается идентификатор изготовителя, идентификатор продукта, номер интерфейса, последние 64 бита серийного номера в UTF-16; может использоваться в сокращённой форме (без указания начала последовательности узлов)
      15. Unit - указывается LUN
      16. Sata - указывается номер порта HBA и номер порта мультипликатора портов (0xFFFF при отсутствии мультипликатора) и LUN например: "PciRoot(0x0)/Pci(0x1f,0x2)/Sata(1,0,0)"
      17. iSCSI - указывается сетевой протокол (TCP), опции регистрации, LUN, имя узла исполнителя, портальная группа (TPGT), например: "PciRoot(0)/Pci(19,0)/Mac(001320F5FA77,0x01)/IPv4(192.168.0.100,TCP,Static,192.168.0.1)/iSCSI(iqn.1991-05.com.microsoft:iscsitarget-iscsidisk-target,0x1,0x0,None,None,None,TCP)/HD(1,GPT,15E39A00-1DD2-1000-8D7F-00A0C92408FC,0x22,0x2710000)"
      18. VLAN - указывается идентификатор VLAN
      19. FibreEx - FibreChannel расширенный - указывается WWN и LUN в виде массива байт (в FC принят порядок следования байт big endian, в UEFI - liitle endian)
      20. SasEx - SAS расширенный (в виде массивов, чтобы избежать борьбы маленьких и больших индейцев) - указывается SAS адрес исполнителя, LUN, топология и порт исполнителя
      21. NVMe - NVM Express - указывается идентификатор пространства имён (NSID), IEEE Extended Unique Identifier (EUI-64)
      22. URI - указывается URI
      23. UFS (Universal Flash Storage) - указывается PUN и LUN
      24. SD - Secure Digital - указывается номер слота
      25. Bluetooth - указывается адрес Bluetooth
      26. Wi-Fi - указывается SSID
      27. eMMC - указывается номер слота
      28. BluetoothLE - указывается адрес Bluetooth и тип адреса
      29. DNS - указываются адреса DNS серверов
    4. Media Device Path - MediaPath(подтип,данные) - внутренности устройства
      1. HD - указываются номер раздела (0 - весь диск), формат таблицы разделов (1 - MBR, 2 - GPT), тип уникального идентификатора раздела и уникальный идентификатор раздела (GUID для GPT), начальный сектор раздела (LBA), размер раздела; может использоваться в сокращённой форме (GUID достаточно для поиска), например: "HD(2,GPT,aa23ecbc-796d-46a1-a852-a3ca1b43c329,0x1f4800,0x64000)"
      2. CDROM (ISO-9660 и El Torito) (no emulation, идентификатор платформы 0xEF) или UDF 2.0 (UDF Bridge) - указываются номер загрузочной записи в каталоге, относительный LBA начала раздела, размер раздела
      3. VenMedia - указывается GUID поставщика и пр. параметры
      4. File - полное имя файла в стандарте системного раздела EFI, можно разбивать на несколько узлов, добавление '\' между узлами и удаление лишних '\' производится автоматически; может использоваться в сокращённой форме, например: "HD(2,GPT,aa23ecbc-796d-46a1-a852-a3ca1b43c329,0x1f4800,0x64000)/File(\EFI\centos\shimx64.efi)"
      5. Media - указывается GUID протокола
      6. PI Firmware File, например: "FvVol(cdbb7b35-6833-4ed6-9ab2-57d2acddf6f0)/FvFile(462caa21-7614-4503-836e-8ab6f4662331)"
      7. PI Firmware Volume, например: "FvVol(cdbb7b35-6833-4ed6-9ab2-57d2acddf6f0)"
      8. Offset (смещение от начала устройства) - указывюется смещение первого байта и смещение последнего байта
      9. RamDisk - указываются начальный адрес памяти, конечный адрес памяти, тип диска (GUID из ACPI NFIT: EFI_VIRTUAL_DISK_GUID - VirtualDisk(), EFI_VIRTUAL_CD_GUID - VirtualCD(), EFI_PERSISTENT_VIRTUAL_DISK_GUID - PersistentVirtualDisk(), EFI_PERSISTENT_VIRTUAL_CD_GUID - PersistentVirtualCD()), номер экземпляра
    5. BIOS Boot Specification Device Path - BbsPath(подтип,данные) - для загрузки в режиме BIOS
      1. BBS (BIOS Boot Specification Version 1.01) - указываются тип устройства (01h - флоппи, 02h - НЖМД, 03h - CD-ROM, 04h - PCMCIA, 05h - USB, 06h - встроенная сеть, 80h - BEV (Bootstrap Entry Vector)), текст описания устройства (ASCII), флаг состояния
    6. End of Hardware Device Path - конец цепочки, подтипы:

    Для создания и манипуляции путями используется EFI_DEVICE_PATH_UTILITIES_PROTOCOL (узнать размер, сделать копию, добавить путь, добавить узел, создать узел, добавить путь в список, извлечь путь из списка).

    Текстовая консоль

    Протоколы поддержки текстовой консоли (устройства ConIn, ConOut, ConErr) используются для ввода и вывода текстовой информации во время работы сервисов загрузки, нет поддержки устройств указания и вывода битовых карт:

    Консоль может быть реализована через последовательный порт или сеть.

    UEFI Simple Text Output может быть реализован с помощью VGA или видеоконтроллера (Graphics Output Protocol - GOP, Block Transfer - BLT).

    Переменные EFI

    Переменные EFI (идентифицируются по GUID производителя и имени; каждый изготовитель прошивки имеет свой физический формат хранения: Intel - VSS, AMI - NVAR)

    Переменные RT без NV во время работы ОС можно только читать.

    Глобальные переменные (GUID 8be4df61-93ca-11d2-aa0d-00e098032b8c):

    Почти все настройки хранятся в переменной с именем Setup (обнаружил у себя ec87d643-eba4-4bb5-a1e5-3f3e36b20da9-Setup, 01239999-fc0e-4b6e-9e79-d54d5db6cd20-Setup и ec87d643-eba4-4bb5-a1e5-3f3e36b20da9-BmcSetup).

    Переменные с атрибутом BS недоступны при работе ОС, но доступны через EFI Shell.

    Переменные EFI и Linux

    Доступны ОС при загрузке в режиме UEFI (/usr/share/doc/kernel-doc-*/Documentation/filesystems/efivarfs.txt)

    Если переменные недоступны, то вы загрузились в режиме BIOS.

    Для работы с переменными EFI можно использовать утилиту efivar (пакеты efivar-libs.x86_64, efivar.x86_64, efivar-devel.x86_64). Ключи:

    Для платформы Intel можно использовать утилиту syscfg:

    syscfg /bvar {create | overwrite} имя-EFI-переменной GUID значение [3 | 7]
    

    Ключ ядра efi_no_storage_paranoia отключает защитные механизмы записи в переменные UEFI (иногда ядро собрано так, что переменые можно только читать), что поможет вам окирпичить свой компьютер.

    Менеджер загрузки

    Загрузка (фаза Boot Device Selection, BDS) может производиться в режиме UEFI или CSM (Compatibility Support Module) для совместимости с BIOS (legacy mode). Выбор производится явно или неявно (например, обнаружение загрузочного устройства в формате MBR может приводить к переходу в режим совместимости). Некоторые дополнительные устройства имеют прошивку только для BIOS (CSM) и если они требуются вывода сообщений или загрузки, то загружаться придётся в CSM режиме. Но с UEFI. CSM также может потребоваться при расхождении битности UEFI и UEFI приложения. Установщик ОС, загруженный в режиме BIOS, не сможет добавить установленную ОС в список загрузки UEFI. BIOS не знает, с какого устройства будет загрузка, поэтому будит всех, менеджер загрузки UEFI в начале будит только ту цепочку устройств, которые необходимы для загрузки драйверов и первого источника загрузки.

    Предусмотрены различные режимы загрузки: режим восстановления (перемычка, инициализировать только устройство для чтения образа восстановления и восстановление прошивки или запускать DXE с резервного тома), обновление прошивки (новую версию прошивки предварительно где-то сохранили), возвращение из режима S3 (было сохранение в память и не надо её инициализировать, не надо вызывать DXE, надо восстановить состояние и возобновить работу ОС), минимальная конфигурация, полная настройка (из S0, стандартный режим), полная конфигурация и диагностика, с настройками по умолчанию, из S4 (на диск), из S5 (мягкое выключение), из S2.

    Загрузчик должен иметь возможность:

    Для нормальной загрузки в режиме UEFI требуется наличие раздела EFI System Partition (как при использовании GPT, так и MBR), обычно монтируется как /boot/efi, содержащий загрузчики и другие UEFI приложения, например средства диагностики, обновления прошивки и пр.. Для каждой загружаемой ОС в каталоге /EFI/ обычно создаётся подкаталог для хранения её загрузчиков и прочих файлов. Драйверы UEFI позволяют добраться к файлам из других файловых систем (например: btrfs, exFAT, ext2/ext3/ext4, ISO9660, JFS, NTFS, XFS, ZFS и др.).

    Встроенный менеджер загрузки определяет консоль (см. PlatformLang, ConIn, ConOut, ErrOut), загружает драйверы (переменная DriverOrder), подготовительные приложения (переменная SysPrepOrder) и выбирает из упорядоченного (переменная BootOrder) списка источников загрузки (Boot####) первый активный и работоспособный, затем загружает приложение (загрузчик второй ступени (GRUB, rEFInd, Gummiboot, Windows Boot Manager), EFI Shell, диагностическую программу и т.д.), устанавливает сторожевой таймер на 5 минут и запускает приложение. При отсутствии BootOrder менеджер загрузки ищет \efi\BOOT\BOOTX64.EFI (для архитектуры X86-64) на всех мобильных устройствах хранения, которые поддерживают EFI_SIMPLE_FILE_SYSTEM_PROTOCOL (путь файла включает ссылку на устройство и абсолютное имя файла) или EFI_BLOCK_IO_PROTOCOL (пробегает по разделам и пытается найти в них EFI_SIMPLE_FILE_SYSTEM_PROTOCOL) или EFI_LOAD_FILE_PROTOCOL (например, сетевой интерфейс; путь файла включает ссылку на устройство и специфическую для устройства информацию - не используется при загрузке, а передаётся как параметр при запуске; напрямую выдаётся один файл), а затем разделах EFI System Partition фиксированных устройств хранения, найденный путь обрабатывается как будто он был подставлен в PlatformRecovery####. Аналогичный поиск проиводится в рамках устройства, если источник загрузки указывает на EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, но без указания имени файла. Путь к USB устройству может иметь сокращённую форму с указанием USB WWID или класса устройства USB (при поиске придётся включить все устройства). Путь к НЖМД или SSD может иметь сокращённую форму с указанием типа таблицы разделов, номера раздела (0 - весь диск), GUID раздела, смещения и размера (при поиске будут включены все блочные устройства). Сокращённая форма может состоять только из полного имени файла, в этом случае будут перепробованы все устройства, поддерживающие протокол EFI_SIMPLE_FILE_SYSTEM_PROTOCOL или EFI_BLOCK_IO_PROTOCOL. Сокращённая форма может состоять из URI. Загрузка может открыть новые тома с драйверами (ROM платы расширения). Если загрузка была неудачной, то эти драйверы запускаются диспетчером DXE и процедура повторяется. Интерфейс пользователя, в частности, меню загрузчика стандартом не определяется. Информация для менеджера загрузки хранится в NVRAM в глобальных переменных UEFI (номера переменных шестнадцатеричные, 4 знака, без подавления незначащих нулей):

    Описание загрузчиков отделено от их физического расположения (перенести диск недостаточно - надо ещё заполнить переменные менеджера загрузки).

    Менеджер загрузки может самостоятельно изменять загрузочные переменные (в стандарте не описано): удалять ошибочные по его мнению, добавлять свои (например, запуск программы настройки или UEFI Shell). Возможно (но не обязательно) средство ручной настройки источников и порядка загрузки.

    Типы загрузочных устройств (если имя файла не указано, то выбирается файл по умолчанию - "\EFI\BOOT\BOOTx64.EFI"):

    Некоторые реализации предлагают меню источников загрузки по нажатию некоторой кнопки после включения (F6 для платформ Intel).

    Если при загрузке не получается запустить утилиту настройки (Setup, кнопки F2, Del, Fn+F2 и др.), то можно попробовать отсоединить все устройства хранения перед перезагрузкой и зайдя в Setup отключить быструю загрузку.

    Настройка переменных производится средствами встроенного менеджера загрузки или командой bcfg UEFI Shell.

    Настройка менеджера загрузки с помощью efibootmgr

    Утилита efibootmgr (пакет efibootmgr) позволяет редактировать переменные менеджера загрузки, требуется доступ на UEFI переменным через /sys/firmware/efi/vars или /sys/firmware/efi/efivars/, посмотреть текущее состояние (пример после установки системы с размещением /boot и ESP на отдельных mdraid RAID-1), звёздочка - активный источник загрузки (Fv - Firmware Volume, идентифицируется по GUID):

    efibootmgr -v
    
    BootCurrent: 000B
    Timeout: 0 seconds
    BootOrder: 000B,0009,0005,0006,0004,0007,0008,0000,0001,0002,0003,000A,000C
    Boot0000* Enter Setup	FvVol(cdbb7b35-6833-4ed6-9ab2-57d2acddf6f0)/FvFile(462caa21-7614-4503-836e-8ab6f4662331)
    Boot0001  Boot Device List	FvVol(cdbb7b35-6833-4ed6-9ab2-57d2acddf6f0)/FvFile(eec25bdc-67f2-4d95-b1d5-f81b2039d11d)
    Boot0002  Payload Launch	FvVol(cdbb7b35-6833-4ed6-9ab2-57d2acddf6f0)/FvFile(98feaa7f-d726-4d8e-8157-a51ff8beb6e3)
    Boot0003  Network Boot	FvVol(cdbb7b35-6833-4ed6-9ab2-57d2acddf6f0)/FvFile(9e09e6fd-4e16-6468-9b78-bdaeaf609cff)
    Boot0004* UEFI IPv6: Intel I350 Network 00 at Baseboard	PciRoot(0x0)/Pci(0x1c,0x4)/Pci(0x0,0x0)/MAC(a4bf010603c4,1)/IPv6([::]:<->[::]:,0,0)
    Boot0005* UEFI IPv4: Intel I350 Network 00 at Baseboard	PciRoot(0x0)/Pci(0x1c,0x4)/Pci(0x0,0x0)/MAC(a4bf010603c4,1)/IPv4(0.0.0.0:0<->0.0.0.0:0,0,0)
    Boot0006* Launch EFI Shell	FvVol(cdbb7b35-6833-4ed6-9ab2-57d2acddf6f0)/FvFile(c57ad6b7-0515-40a8-9d21-551652854e37)
    Boot0007* UEFI IPv6: Intel I350 Network 01 at Baseboard	PciRoot(0x0)/Pci(0x1c,0x4)/Pci(0x0,0x1)/MAC(a4bf010603c5,1)/IPv6([::]:<->[::]:,0,0)
    Boot0008* UEFI IPv4: Intel I350 Network 01 at Baseboard	PciRoot(0x0)/Pci(0x1c,0x4)/Pci(0x0,0x1)/MAC(a4bf010603c5,1)/IPv4(0.0.0.0:0<->0.0.0.0:0,0,0)
    Boot0009* CentOS	HD(2,GPT,aa23ecbc-796d-46a1-a852-a3ca1b43c329,0x1f4800,0x64000)/File(\EFI\centos\shimx64.efi)
    Boot000A* UEFI SATA0:HGST HTS725050A7E630 	PciRoot(0x0)/Pci(0x1f,0x2)/Sata(0,0,0)
    Boot000B* CentOS	HD(2,GPT,51c99c89-ae76-4638-adc6-235759772589,0x1f4800,0x64000)/File(\EFI\centos\shimx64.efi)
    Boot000C* UEFI SATA1:HGST HTS725050A7E630 	PciRoot(0x0)/Pci(0x1f,0x2)/Sata(1,0,0)
    
    aa23ecbc-796d-46a1-a852-a3ca1b43c329 - это sda2
    51c99c89-ae76-4638-adc6-235759772589 - это sdb2
    cdbb7b35-6833-4ed6-9ab2-57d2acddf6f0 - ?
    
    lsblk
    
    NAME              MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
    sda                 8:0    0 465.8G  0 disk  
    ├─sda1              8:1    0  1000M  0 part  
    │ └─md2             9:2    0 999.4M  0 raid1 /boot
    ├─sda2              8:2    0   200M  0 part  
    │ └─md1             9:1    0   200M  0 raid1 /boot/efi
    └─sda3              8:3    0 464.6G  0 part  
      └─md3             9:3    0 464.5G  0 raid1 
        ├─system-root 253:0    0  19.5G  0 lvm   /
        └─system-swap 253:1    0  58.6G  0 lvm   [SWAP]
    sdb                 8:16   0 465.8G  0 disk  
    ├─sdb1              8:17   0  1000M  0 part  
    │ └─md2             9:2    0 999.4M  0 raid1 /boot
    ├─sdb2              8:18   0   200M  0 part  
    │ └─md1             9:1    0   200M  0 raid1 /boot/efi
    └─sdb3              8:19   0 464.6G  0 part  
      └─md3             9:3    0 464.5G  0 raid1 
        ├─system-root 253:0    0  19.5G  0 lvm   /
        └─system-swap 253:1    0  58.6G  0 lvm   [SWAP]
    

    Если efibootmgr не работает, то вы загрузились в режиме BIOS.

    Ключи efibootmgr (осторожно: можно получить попорченные переменные загрузчика - у меня был неудаляемый источник 1001 и лишний "Enter Setup" первым в списке):

    Установка memtest86 от PassMark (free, 7.4, ISO версия) на сервер с UEFI для прямой загрузки:

    Загрузка Linux в режиме UEFI

    SYSLINUX поддерживает загрузку ядра Linux в режиме UEFI с версии 6 (syslinux.efi, syslinux.cfg).

    GRUB Legacy (0.97) официально не поддерживает загрузку UEFI, но модифицированная версия (Fedora 11 до 17, RHEL 6) - поддерживает загрузку ядра Linux и UEFI приложений, отсутствует поддержка Secure Boot. Пакет grub-0.97-99.el6.x86-64.rpm устанавливает /boot/efi/EFI/redhat/grub.efi, конфигурация grub.conf в том же каталоге, в документации слов EFI и UEFI не обнаружил (grub.info, multiboot.info, grub-crypt.8, grub-install.8, grub-md5-crypt.8, grub-terminfo.8, grub.8). Позволяет загружаться с устройств GPT с размером сектора 4 КиБ со времён RHEL 6.1, с разделов более 2 ТиБ со времён RHEL 6.2.

    GRUB2 поддерживает загрузку ядра Linux, FreeBSD, Mac OS и пр., а также UEFI приложений. Поддерживает (и даже настаивает на) Secure Boot. Отдельные версии для UEFI-32 (grub2-efi-ia32.x86_64, grub2-efi-ia32-cdboot.x86_64, grub2-efi-ia32-modules.noarch) и UEFI-64 (grub2-efi-x64.x86_64, grub2-efi-x64-cdboot.x86_64, grub2-efi-x64-modules.noarch), сам загрузчик всегда 64-битный. Настройки изготавливаются из /etc/default/grub с помощью команды "grub2-mkconfig -o /boot/grub2/grub.cfg" и "grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg".

    При установке CentOS 7 создаётся /boot/efi/EFI/BOOT/BOOTX64.EFI, содержащий копию 64-битного подписанного Microsoft (подпись для чужого ПО) для безопасной загрузки загрузчика shim.efi (загрузчик первой ступени, загружает настоящий загрузчик после проверки подписи). Его копия кладётся (на всякий случай) в /boot/efi/EFI/centos/shim.efi и /boot/efi/EFI/centos/shimx64.efi (shimx64-centos.efi подписан распростанителем вместо Microsoft). Варианты 32- и 64-битных подписанных и неподписанных загрузчиков можно найти в пакетах shim-ia32, shim-unsigned-ia32, shim-x64 и shim-unsigned-x64. Рядом в /boot/efi/EFI/BOOT/fbx64.efi кладётся драйвер графики Frame Buffer для shim и mmx64.efi (MokManager - управление базой ключей MOK), оба подписаны распространителем ("Red Hat Inc.") На загрузчик shim ссылаются в настройках меню /boot/efi/EFI/centos/BOOTX64.CSV и /boot/efi/EFI/centos/BOOT.CSV (совпадают, UCS-2). shim загружает GRUB2 из /boot/efi/EFI/centos/grubx64.efi (его файлы рядом grub.cfg, grubenv и fonts/) из пакета grub2-efi, [проверяет подпись распространителя (Red Hat Secure Boot (CA key 1)?) или из MOK] и запускает. Загрузка модулей GRUB2 не допускается (всё, что посчитали нужным, уже в нём ;), механизма подписи модулей нет). GRUB2 выводит меню (не подписано) для выбора, настройки и загрузки ядра и его верного initrd (не подписано, dracut для RHEL7), [проверяет с помощью shim подпись распространителя (Red Hat Secure Boot (CA key 1)?) или из MOK для собранных ядер] и запускает. Ядро CentOS 7 в режиме безопасной загрузки проверяет (за рамками стандарта) подписи модулей перед их установкой (при каждой сборке ядра генерируются приватные ключи, которыми подписываются модули, публичные ключи встраиваюттся в ядро, приватные - удаляются), также ограничивается (ограничивался?) функционал (setpci, hibernate, kexec, модуль msr, acpi_rspd, /dev/kmem, systemtap kprobe).

    В ESP можно записать ядро Linux, оформленное как UEFI приложение (UEFI boot stub, CONFIG_EFI_STUB, в RHEL 7.4 включено, /usr/share/doc/kernel-doc-3.10.0/Documentation/x86/efi-stub.txt), в этом случае загрузчик вообще не нужен, но возникают проблемы с безопасной загрузкой (надо каждое собранное ядро подписывать основным ключом). Ключи ядра при запуске из UEFI Shell передаются как аргументы UEFI приложения, ключ initrd= позволяет указать абсолютное имя initrd файла в стиле EFS ("fs0:\Kernels> bzImage.efi initrd=\Ramdisks\initrd-large.img"). При запуске из менеджера загрузки параметры придётся прошить в ядро. Также можно в качестве загрузчика указать UEFI Shell и в его скрипте startup.nsh указать ядро с нужными параметрами. Или задать параметры с помощью efibootmgr или команды UEFI Shell или BIOS Setup. Поменять параметры (например, загрузиться в single mode) при загрузке нельзя.

    Пример прямой загрузки (обратите внимание на формат initrd, и он д.б. в начале строки):

    Формально поддержка UEFI и GPT в RHEL 7 имеется и улучшается (например, в RHEL 7.2 в kickstart) была добавлена команда reqpart для создания ESP раздела), но напильник понадобится (установка на md вручную, memtest86+ не работает в UEFI.

    ?Загрузка и установка PXE

    PXE
            if option architecture-type = 00:07 {
              filename = "uefi/shim.efi"; из пакета shim в CentOS 7, он же в /boot/efi/EFI/centos/shim.efi
            } else {
    # из system-config-netboot-cmd в CentOS 5 или syslinux-tftpboot в CentOS 6/7
              filename "linux-install/pxelinux.0";
    
    В тот же каталог, что и shim.efi положить настройки grub.cfg, grubx64.efi (взять из пакета grub2-efi в CentOS 7), туда же скопировать initrd.img и vmlinuz из images/pxeboot установочного DVD-ROM, туда же BOOT.CSV и BOOTX64.CSV, BOOTX64.EFI (совпадает с shim.efi и shimx64.efi), fallback.efi (?), MokManager.efi (?), shim-redhat.efi (?)

    Быстрая загрузка

    Отказ от инициализации USB в фазе DXE/BDS экономит целых 0.5 секунды (и ещё 0.5 секунды на ожидание ввода), правда при этом нельзя нажать клавишу входа в настройки, т.к. USB клавиатура не работает. И как обновляться с USB устройств?

    Отказ от загрузки в режиме CSM экономит время - опциональные ROM карт расширения могут ждать ввода пользователя для вызова программы конфигурации (2 секунды на сетевой карте Intel); опциональные ROM карт расширения должны быть запущены все и каждый ROM перебирает всё дерево устройств в поиске "своего" контроллера. Без CSM можно инициализировать только минимальный набор устройств, необходимых для загрузки (3 секунды на обычном ПК), правда, не все устройства могут включиться (ОС должна проинициализировать устройство самостоятельно).

    Отказ от CSM позволяет инициализировать только консоль и первое устройство из BootOrder вместо всего подряд (если в BootOrder не использовано сокращённое описание загрузочного устройства в виде GUID раздела или класса устройства).

    Отключение графической заставки экономит 0.3 секунды на инициализации графики и неизвестно сколько на демонстрации картинки.

    SSD (не Intel X25-E ;) экономит несколько секунд.

    Прямая загрузка ядра вместо shim-grub2-kernel, но нужно оставить "чёрный ход" для варианта загрузки с редактированием параметров ядра.

    Сервисы периода выполнения

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

    Минимальный набор сервисов:

    Для kexec требуется информация об отображении виртуальных адресов, (/usr/share/doc/kernel-doc-*/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map), которая хранится в каталоге /sys/firmware/efi/runtime-map (EFI_MEMORY_ATTRIBUTES_TABLE), каждый подкаталог (0/, 1/ и т.д.) содержит информацию об регионе памяти (текстовое представление, шестнадцатеричный вид): attribute, num_pages, phys_addr, type, virt_addr. На платформе Intel H2000G занято изрядно:

    [    0.000000] efi: EFI v2.40 by EDK II BIOS ID:SE5C610.86B.01.01.0022.062820171903
    [    0.000000] efi:  SMBIOS=0x7a223000  ACPI=0x7b7cc000  ACPI 2.0=0x7b7cc014 
    [    0.000000] efi: mem319: type=6, attr=0x800000000000000f, range=[0x000000007a127000-0x000000007a227000) (1MB)
    [    0.000000] efi: mem320: type=5, attr=0x800000000000000f, range=[0x000000007a227000-0x000000007a327000) (1MB)
    [    0.000000] efi: mem328: type=11, attr=0x8000000000000000, range=[0x0000000080000000-0x0000000090000000) (256MB)
    [    0.000000] efi: mem329: type=11, attr=0x8000000000000000, range=[0x00000000fed1c000-0x00000000fed20000) (0MB)
    [    0.000000] SMBIOS 2.7 present.
    [    0.000000] DMI: Intel Corporation S2600TPR/S2600TPR, BIOS SE5C610.86B.01.01.0022.062820171903 06/28/2017
    

    Работа с капсулами в пакетах fwupdate (утилита /usr/bin/fwupdate, "--list", "--supported" (Intel H2000Z нет поддержки, требуется UEFI 2.5), "--info"), fwupdate-efi (приложение UEFI /boot/efi/EFI/centos/fwupx64.efi) и fwupdate-libs. Манипулирует переменной UEFI с именем fwupdate и GUID 0abba7dc-e516-4167-bbf5-4d9d1c739416, а также перемеными менеджера загрузки для установки и загрузки приложения UEFI для обновления прошивки в /boot/efi/EFI/centos/fw/fwupdate-* (флажок /usr/share/fwupdate/done).

    Использование сервисов времени выполнения ядром Linux можно отключить (/usr/share/doc/kernel-doc-3.10.0/Documentation/x86/x86_64/uefi.txt) при загрузке ядра ключами noefi (все) и reboot_type=k (только сервис перезагрузки). Если карта памяти UEFI (UEFI MemMap) шире карты памяти E820, то её можно добавить ключом add_efi_memmap при загрузке (включено по умолчанию). Ключ ядра efi_no_storage_paranoia отключает защитные механизмы записи в переменные UEFI (иногда ядро собрано так, что переменые можно только читать).

    UEFI Shell

    UEFI Shell - приложение UEFI, обеспечивает интерактивную командную оболочку для работы с консоли, набор команд и обработку скриптов (.nsh, ASCII или UCS-2), может запускать приложения UEFI и скрипты из ПЗУ или устройств хранения, для которых имеются UEFI драйвера. В частности, умеет работать с системным разделом и прочими файловыми системами FAT112/FAT16/FAT32. Также работает с переменными менеджера загрузки, разделами, файлами, имеется текстовый и шестнадцатеричный редактор, инструменты исследования аппаратуры. Может быть встроенным в прошивку (например, Intel использует UEFI Shell как средство обновления прошивки, вызывается из меню загрузки). Обеспечивает API для запущенных приложений (разбор и выполнение командной строки и т.д.). Имеет средства работы с историей команд (стрелки вверх и вниз). Выполнение скриптов, команд и приложений можно прервать нажатием Ctrl-C (не обязательна поддержка прерывания команд и приложений). Ошибка в командах скрипта не останавливает его выполнение, кроме команд for, endfor, if, else, endif и goto. Вывод на консоль можно приостанавливать нажатием Ctrl-S и возобновлять любой клавишей. Буфер вывода (минимум 3 экрана) можно листать клавишами PageUp и PageDown во время ожидания. Скрипты могут быть вложенными, включая рекурсию. Дополнительные команды могут быть добавлены драйверами.

    Стандарт определяет 4 уровня поддержки (в версии 2 появились профили):

    Имя приложения или скрипта для запуска указывается в качестве параметра shell.efi, после чего можно задать параметры приложения. При этом подразумевается ключ '-nostartup' (см. ниже). Все имена и параметры задаются в UCS-2. Опции запуска (перед параметром):

    При инициализации оболочки пути устройств (device path) отображаются на имена файловых системы (fsX:) и блочные устройства (blkX:), читается список синонимов и переменных окружения из ПЗУ, в переменную окружения profiles читается список профилей (не обнаружен), ищется (сначала в каталоге запуска самого shell.efi, затем в списке из переменной окружения PATH (".")) и запускается startup.nsh (см. -startup и -nostartup).

    Имена команд, файлов, переменных и пр. нечувствительны к регистру и разделяются пробелами и табуляциями. Поддерживаются синонимы команд (alias). Подстановка значений переменных окружения осуществляется символами '%' вокруг имени переменной, позиционных переменных (от 0 - полное имя скрипта до 9) - символом '%' перед номером позиции, индексных переменных - символом '%' перед буквой создаваемого командой for индекса. Комментарии начинаются символом '#'. Метки начинаются символом ':'. Специальные символы (включая пробел) окружаются двойными кавычками (подстановка значений переменных не отменяется). Специальное значение символа блокируется символом '^' даже внутри кавычек. Шаблоны имён файлов задаются с использованием символов '*' (любое число символов), '?' (1 любой символ, '[' и ']' (1 символ из перечисленных в скобках) в "некоторых местах" ('^' не действует). Символ '@' в начале строки отключает вывод текста команды на консоль ("echo -off" отключает для всех следующих команд).

    Перенаправление ввода и/или вывода в файл или переменную окружения или другую команду, специальные имена файлов NUL или NULL никуда не пишут:

    Имена переменных окружения чувствительны к регистру (в реализации версии 1 от Intel - нет). Могут храниться как переменные UEFI в NVRAM (под именем "SEnv:имя", атрибуты - NV+BS; GUID - ?) или пропадать при перезагрузке ("set -v имя значение", атрибуты - BS). Некоторые имена зарезервированы:

    Переменные UEFI отображаются по возможности с именами пространства имён вместо GUID (для регистрации своего имени пространства имён используется RegisterGuidName), например "Efi:PlatformLangCodes" вместо "8be4df61-93ca-11d2-aa0d-00e098032b8c:PlatformLangCodes".

    Для каждой файловой системы независимо ведётся текущий каталог (как в PC DOS), ведётся текущая файловая система, которые используются при отсутствии файловой системы и/или каталога в имени файла. Имена каталогов разделяются символом '\'. Имя файловой системы выглядит как 'fs', затем её номер, затем ':\'. Длина полного имени файла не может быть более 255 символов (UCS-2?). Начальное отображение путей устройств на файловые имена "fsX:" (и "map -r") не должно изменяться при перезагрузке при неизменном списке оборудования (безумный ad hoc на 16 страниц ради получения "консистентных" имён, лучше просто верить, что вставленная флешка всегда будет "fs0:").

    Общие ключи команд (не у всех команд, ключи нельзя конкатенировать - "-v -b", но не "-vb"):

    Команды:

    UEFI Secure Boot

    Secure Boot есть расширение UEFI (UEFI 2.3.1 и новее), призванное уменьшить вероятность загрузки нехорошего кода.

    При включении безопасной загрузки производится переход в режим установки (Setup, 8be4df61-93ca-11d2-aa0d-00e098032b8c-SetupMode=1), в котором возможна установка публичных ключей платформы (PK, самоподписанный сертификат X509v2, заносится изготовителем), после чего производится переход в режим использования (User). Приватные ключи платформы используются для подписи заявок на изменение базы ключей KEK (Key Exchange Keys, авторизованный пользователь, подписанный приватным ключом PK сертификат X509v2, в каждом компьютере с логотипом "Windows 8 Ready" д.б. Microsoft Corporation KEK CA). Приватные ключи KEK используются для подписи заявок на изменение базы ключей DB (доверенные ключи для цифровой подписи приложений, в каждом компьютере с логотипом "Windows 8 Ready" д.б. Microsoft Windows Production PCA и Microsoft Corporation UEFI CA, а также обычно добавляются ключи изготовителя для утилит) и DBX (приложения, подписанные этими ключами или имеющие указанный хеш, запрещены). Рекомендуется проверить PK, KEK и DB при покупке - не поставил ли изготовитель или продавец чего лишнего. В режиме User возможна загрузка только подписанных приватным ключами DB загрузчиков (приложений), прошивок карт расширений (OpROM, например, PXE загрузка) и драйверов. Возможен перевод в режим Custom, в котором возможно добавление пользователем произвольных публичных ключей в DB. Возврат в режим Setup происходит при удалении ключей платформы (д.б. пункт в меню настройки). При манипуляции с ключами используется инфраструктура Public Key Infrastructure (PKI), для подписи используется приватный ключ (тайный), для проверки - соответствующий ему публичный (открытый) ключ. Microsoft предлагает сервис цифровой подписи посторонних программ (кроме программ под GPLv3) своим ключом Microsoft Corporation UEFI CA, в частности им подписаны загрузчики shim и PreLoader. Какова дата завершения сертификата и проверяется ли она (сертификат Microsoft с 2011 по 2026 год)? Утилита Intel BOOTUTIL64E.EFI не подписана, подозреваю, что другие тоже могут оказаться не подписаны (iflash32.efi подписана от "Intel(R) PCSD commercial utilities"). Активированность проверяется по значению UEFI переменной /sys/firmware/efi/efivars/8be4df61-93ca-11d2-aa0d-00e098032b8c-SecureBoot:

    efivar -p --name 8be4df61-93ca-11d2-aa0d-00e098032b8c-SecureBoot
    GUID: 8be4df61-93ca-11d2-aa0d-00e098032b8c
    Name: "SecureBoot"
    Attributes:
            Boot Service Access
            Runtime Service Access
    Value:
    00000000  00
    
    bootctl status
    System:
       Machine ID: f443e7ac8f604c8dbbc3203bc02099d1
          Boot ID: ce9c41ed188943f586958cfcf4041714
      Secure Boot: disabled
       Setup Mode: setup
    
    Selected Firmware Entry:
            Title: Direct CentOS 7.4
        Partition: /dev/disk/by-partuuid/aa23ecbc-796d-46a1-a852-a3ca1b43c329
             File: └─/EFI/centos/vmlinuz-3.10.0-693.5.2.el7.x86_64
    
    

    Глобальные переменные UEFI: dbDefault, dbrDefault, dbtDefault, dbxDefault, KEK, KEKDefault, PK, PKDefault, SignatureSupport (список алгоритмов подписей), SecureBoot, SetupMode (в режиме Setup не требуется аутентификация для изменения переменных безопасной загрузки), VendorKeys (1 - только ключи поставщика).

    Используются алгоритмы хеширования SHA-1 и SHA-256, ассиметричное шифрование RSA2048 и Authenticode (?).

    Загрузчик shim (Fedora, RHEL, CentOS, Ubuntu, SUSE, Alt) в режиме User перед запуском приложения проверяет, что оно подписано или его хеш имеется в NVRAM в базе допустимых MOK. shim воспринимает ключи: встроенные в прошивку (или добавленные пользователем) DB, встроенные в shim распространителем (в CentOS - "Red Hat Inc.", в Fedora - "Fedora CA"), переменной UEFI MOK (Machine Owner Key, 605dab50-e046-4300-abb6-3dd810dd8b23-MokListRT, не является частью стандарта UEDI). shim настроен на загрузку приложения с именем grubx64.efi (необязательно настоящий GRUB2). Вместе с shim поставляются подписанные распространителем MokManager.efi (управление базой MOK, mmx64.efi) и fbx64.efi (драйвер frame buffer), который вызывается при неудачной проверке подписи загружаемого приложения и позволяет добавить X509v2 сертификат из файла или хеш в ESP в базу MOK (выбор из найденных им разделов, затем выбор файла) и продолжить загрузку. Загруженное приложение в зависмости от возможности может загружать всё подряд, загружать подписанные PK приложения, загружать подписанные MOK приложения (настоящий GRUB2 обращается к shim). Пример процесса загрузки для CentOS 7. Менеджер загрузки UEFI не обращается к MOK.

    Загрузчик PreLoader вычисляет хеш загружаемого приложения loader.efi и проверяет её наличие в базе допустимых в NVRAM, не умеет работать с подписями, утилита работы с базой - HashTool.efi. Обеспечивает доступ любых UEFI приложений к MOK.

    Утилита mokutil (пакет mokutil) позволяет работать с базой MOK.

    Ключи действия mokutil:

    Опции mokutil:

    Регистрация ключа RedHat для бета версий:

    1. отключить UEFI Secure Boot
    2. установить Linux
    3. mokutil --import /lib/modules/$(uname -r)/kernel-signing-ca.cer # /usr/share/doc/kernel-keys/3.10.0-693.5.2.el7/kernel-signing-ca.cer?
    4. выбрать и ввести пароль
    5. перезагрузиться, включив UEFI Secure Boot
    6. подтвердить импорт сертификата и ввести пароль
    7. любые ядра, подписанные ключом RedHat для бета версий будут загружаться, пока сертификат не будет удалён

    Удаление импортированных сертификатов:

    1. mokutil --reset
    2. перезагрузиться
    3. подтвердить удаление сертификата и ввести пароль

    Утилита pesign (пакет pesign) позволяет подписывать UEFI приложения, примеры подписанных приложений (информации негусто - сертификат отсоединён, надо его где-то взять и запихнуть в базу /etc/pki/pesign)

    pesign --verbose --show-signature --signature-number=0 --in=/boot/efi/EFI/BOOT/BOOTX64.EFI # shimx64.efi
    ---------------------------------------------
    certificate address is 0x7f327a7e9580
    Content was not encrypted.
    Content is detached; signature cannot be verified.
    The signer's common name is Microsoft Windows UEFI Driver Publisher
    No signer email address.
    No signing time included.
    There were certs or crls included.
    
    pesign --verbose --show-signature --signature-number=0 --in=/boot/efi/EFI/centos/shim.efi
    ---------------------------------------------
    certificate address is 0x7fb1d01c4580
    Content was not encrypted.
    Content is detached; signature cannot be verified.
    The signer's common name is Microsoft Windows UEFI Driver Publisher
    No signer email address.
    No signing time included.
    There were certs or crls included.
    
    pesign --verbose --show-signature --signature-number=0 --in=/boot/efi/EFI/centos/shimx64-centos.efi
    ---------------------------------------------
    certificate address is 0x7f04eef32b68
    Content was not encrypted.
    Content is detached; signature cannot be verified.
    The signer's common name is Red Hat Inc.
    No signer email address.
    Signing time: Fri Sep 01, 2017
    There were certs or crls included.
    
    pesign --verbose --show-signature --signature-number=0 --in=/boot/efi/EFI/centos/mmx64.efi
    ---------------------------------------------
    certificate address is 0x7fdb62337568
    Content was not encrypted.
    Content is detached; signature cannot be verified.
    The signer's common name is Red Hat Inc.
    No signer email address.
    Signing time: Fri Sep 01, 2017
    There were certs or crls included.
    
    pesign --verbose --show-signature --signature-number=0 --in=/boot/efi/EFI/BOOT/fbx64.efi
    ---------------------------------------------
    certificate address is 0x7fcc67293550
    Content was not encrypted.
    Content is detached; signature cannot be verified.
    The signer's common name is Red Hat Inc.
    No signer email address.
    Signing time: Fri Sep 01, 2017
    There were certs or crls included.
    
    pesign --verbose --show-signature --signature-number=0 --in=/boot/efi/EFI/centos/grubx64.efi
    ---------------------------------------------
    certificate address is 0x7f4c89c5bc08
    Content was not encrypted.
    Content is detached; signature cannot be verified.
    The signer's common name is Red Hat Inc.
    No signer email address.
    Signing time: Sat Oct 21, 2017
    There were certs or crls included.
    
    pesign --verbose --show-signature --signature-number=0 --in=/boot/efi/EFI/centos/vmlinuz-3.10.0-693.5.2.el7.x86_64
    ---------------------------------------------
    certificate address is 0x7f034e7f52e8
    Content was not encrypted.
    Content is detached; signature cannot be verified.
    The signer's common name is Red Hat Inc.
    No signer email address.
    Signing time: Fri Oct 20, 2017
    There were certs or crls included.
    
    pesign --verbose --show-signature --signature-number=0 --in=/boot/efi/EFI/memtest/BOOTX64.MEMTEST86-74.EFI
    ---------------------------------------------
    certificate address is 0x7f36f6ccb1a8
    Content was not encrypted.
    Content is detached; signature cannot be verified.
    The signer's common name is Microsoft Windows UEFI Driver Publisher
    No signer email address.
    No signing time included.
    There were certs or crls included.
    
    

    Ядро импортирует ключи из базы UEFI:

    keyctl list %:.system_keyring
    3 keys in keyring:
    225464260: --alswrv     0     0 asymmetric: CentOS Linux kpatch signing key: ea0413152cde1d98ebdca3fe6f0230904c9ef717
    171859011: --alswrv     0     0 asymmetric: CentOS Linux kernel signing key: c757a9fbbd0d82c9e54052029a0908d17cf1adc7
    718091548: --alswrv     0     0 asymmetric: CentOS Linux Driver update signing key: 7f421ee0ab69461574bb358861dbe77762a4201b
    
    при включённом Secure Boot д.б. аппаратные ключи
    6 keys in keyring:
    ...asymmetric: Red Hat Enterprise Linux Driver Update Program (key 3): bf57f3e87...
    ...asymmetric: Red Hat Secure Boot (CA key 1): 4016841644ce3a810408050766e8f8a29...
    ...asymmetric: Microsoft Corporation UEFI CA 2011: 13adbf4309bd82709c8cd54f316ed...
    ...asymmetric: Microsoft Windows Production PCA 2011: a92902398e16c49778cd90f99e...
    ...asymmetric: Red Hat Enterprise Linux kernel signing key: 4249689eefc77e95880b...
    ...asymmetric: Red Hat Enterprise Linux kpatch signing key: 4d38fd864ebe18c5f0b7...
    

    Утилита sbsign также позволяет подписывать UEFI приложения (не нашёл в дистрибутиве, совпадение имени утилиты - keytool - с Java). KeyTool.efi позволяет в режиме Setup (возможног придётся очистить все базы Secure Boot) управлять ключами PK, KEK, DB и MOK.

    Коллекция сертификатов (microsoft-pca-public.der - этим ключом Microsoft подписывает свои загрузчики, microsoft-uefica-public.der - этим ключом Microsoft подписывает чужие приложения).

    Проблемы реализации Secure Boot с помощью поставляемого в дистрибутиве shim (метод борьбы):

    А ещё есть Secure Boot (Verified Boot, ранее PFAT) от Intel (2012), переименованный в Intel Boot Guard (2013) - программа проверки подписи прошивки перед её запуском.

    Ссылки

    @ Карта сайта News Автора!

    Bog BOS: hardware:  EFI, UEFI и PI

    TopList

    Copyright © 1996-2017 Sergey E. Bogomolov; www.bog.pp.ru (КГБ знает все, даже то что у Вас на диске ;)