- PVSM.RU - https://www.pvsm.ru -
В первой части этой статьи [1] мы познакомились с форматом UEFI Capsule и Intel Flash Image. Осталось рассмотреть структуру и содержимое EFI Firmware Volume, но для понимания различий между модулями PEI и драйверами DXE начнем с процесса загрузки UEFI, а структуру EFI Firmware Volume отставим на вторую часть.
С высоты птичьего полета процесс загрузки UEFI выглядит так:
Вообще говоря, нас интересует не весь это процесс, а его часть — Platform Initialization (PI), которая делится на 3 фазы: SEC, PEI и DXE.
Всю документацию по PI можно свободно загрузить с сайта UEFI Forum [2]. Фазы SEC и PEI описаны в Volume 1, фаза DXE — в Volume 2, общие архитектурные элементы, в том числе интересующие нас форматы файлов и заголовков EFI FFS — в Volume 3, субфаза SMM (стартует в середине DXE и идет параллельно) — в Volume 4, стандарты на совместимое с PI оборудование и ПО — в Volume 5. Про оборудование и ПО здесь я писать не стану, а вот остальные фазы нужно упомянуть, т.к. не зная их, сложно понять, зачем в файле BIOS'а столько всего и чем это всё отличается друг от друга.
Первая фаза загрузки, задачи которой следующие:
По факту, на IA64 фаза SEC проходит так:
Видно, что в участникам фазы SEC из образа BIOS понадобятся как минимум хранящиеся там патчи для микрокода CPU, а также адрес и размер Boot Firmware Volume. Да и сам код SEC записан в той же микросхеме и пока еще выполняется там же.
Вторая фаза, основная задача которой — инициализировать достаточное количество непрерывной RAM для того, чтобы можно было запустить фазу DXE, подготовить и передать в фазу DXE данные об обнаруженных устройствах, чтобы драйверы DXE смогли их правильно инициализировать. Исполняемый код PEI состоит из ядра, называемого PEI Foundation, которое является общим для процессоров с одинаковой архитектурой и модулей PEIM, выполняющих начальную инициализацию конкретных устройств и разработанные производителями этих устройств. Модули поддержки Chain of Trust, выполняющие проверку валидности других модулей, также могут присутствовать. Архитектура PEI позволяет независимую разработку и отладку модулей, и никто не мешает написать и интегрировать свой собственный модуль, если понадобится.
У PEIM может присутствовать список зависимостей от других модулей, поэтому порядок их запуска не случаен и выбирается диспетчером PEI. Модули PEIM могут заполнять независимые от позиции структуры данных — HOB'ы, в которых содержатся данные для передачи драйверу DXE и GUID этого драйвера.
По факту, на IA64 фаза PEI происходит так:
Таким образом, при S3 Resume запуск фазы DXE не происходит вообще, что позволяет сильно ускорить загрузку. При включении FastBoot загрузку можно ускорить еще сильнее, выполняя минимальный набор тестов и модулей PEIM.
Видно, что в фазе PEI из образа BIOS нужны будут как минимум PEI Foundation и модули для всего оборудования, нуждающегося в ранней инициализации. Также стоит рассказать о том, что формат модулей PEI может как совпадать с форматом драйверов DXE (PE32+), так и отличаться от него заголовком, т.к. заголовок PE32+ содержит множество неиспользуемых в фазе PEI полей, а место в кэше процессора не резиновое. Поэтому для PEIM был разработан специальный формат TE, заголовок которого содержит только необходимые поля. TE бывают исполняемые-на-месте (XIP), перемещаемые (relocatable) и независимые от позиции (PIC). Также встречаются гибридные DXE/PEI-модули с двумя точками входа, но они обязаны быть в формате PE32+, поскольку иначе как драйвер DXE такой модуль не запустится.
Здесь выполняется основная и окончательная инициализация всего на основе полученных от PEI HOB'ов. Код DXE состоит из ядра, оно же DXE Foundation, диспетчера и драйверов. Ядро инициализирует и запускает различные службы UEFI: Boot Services, Runtime Services и DXE Services. Диспетчер отвечает за поиск и запуск DXE-драйверов, которые также имеют зависимости. Драйверы проводят окончательную инициализацию аппаратуры и предоставляют аппаратную абстракцию для служб. Весь код DXE, кроме Runtime-частей Foundation и Runtime DXE драйверов выгружается из памяти по окончанию фазы BDS, которую я здесь рассматривать не буду.
Расписывать досконально процесс запуска DXE тоже нет смысла, можно описать его в двух словах: загружается ядро, создает нужные структуры данных, затем запускается диспетчер и грузит все доступные драйверы со всех доступных носителей, затем запускается бутлоадер и пытается найти на этих носителях загрузчик ОС и передать ему управление. Если нашелся — отлично, если нет — пробуем дальше, пока не найдем. Если так ничего и не нашли — выполняем код модуля Platform Policy, который для нас написал производитель материнской платы, выводящий нам сообщение о том, что «Operating System is missing».
Видно, что из образа BIOS'а для этой фазы нужны DXE-драйверы и все, что им может понадобится. Большая часть файлов в EFI FS используется именно здесь.
Во время фазы DXE наступает момент, когда диспетчер загружает драйвер SMM Init, с которого и начинается эта субфаза. SMM — специальный режим процессора, в который он переходит при получении специального прерывания — SMI, которое может быть как программным, так и аппаратным. Большую часть (или вообще все) источников SMI можно отключить, если переход в SMM не требуется. Код SMM выполняется в SMRAM, которая становится недоступной для ОС после окончания фазы DXE, поскольку драйвер SMM намеренно закрывает к ней доступ. Код SMM выполняется и после окончания фазы DXE, до самого выключения ПК.
Драйвер SMM Init открывает SMRAM, создает ее карту и структуры данных, необходимые для запуска других драйверов SMM, а перед окончанием фазы DXE закрывает доступ к SMRAM полностью. Драйверы SMM зависят от оборудования и не имеют доступа к EVM, поэтому написание драйверов SMM на EBC не поддерживается. Бывают эти самые драйверы двух видов: чистые SMM, которые загружаются Init-ом непосредственно в SMRAM, и SMM/DXE-гибриды, которые сначала запускаются диспетчером DXE, а потом уже копируют часть себя в SMRAM. Сам SMM Init — именно такой гибрид.
Видно, что для этой субфазы из образа BIOS'а нужны драйверы SMM.
Теперь вы знаете, как происходит загрузка UEFI и какие модули необходимы для нее.
Я принял решение разделить планируемую вторую часть еще на две, чтобы уменьшить размер поста и снизить когнитивную нагрузку на читателя.
Во второй части статьи мы наконец рассмотрим структуру файла EFI FV, и сведения из этой вам там очень пригодятся.
Спасибо за внимание.
Автор: CodeRush
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/uefi/38132
Ссылки в тексте:
[1] первой части этой статьи: http://habrahabr.ru/post/185704/
[2] загрузить с сайта UEFI Forum: http://www.uefi.org/specs/download_platform/
[3] Analysis of the building blocks and attack vectors associated with the Unified Extensible Firmware Interface (UEFI), Paper by Jean-François Agneessens: http://www.sans.org/reading_room/whitepapers/services/analysis-building-blocks-attack-vectors-unified-extensible-firmware_34215
[4] Reducing Platform Boot Time, Paper by Michael Rothman, Genliu Xing, Yan Wang and Jiong Gong: http://www.intel.de/content/dam/www/public/us/en/documents/white-papers/reducing-platform-boot-time-paper.pdf
[5] UEFI Platform Initialization Specification 1.2.1 Errata A, Documents by UEFI Forum: http://www.uefi.org/specs/download_platform/PI_1_2_1_errataA.zip
[6] Источник: http://habrahabr.ru/post/185764/
Нажмите здесь для печати.