Подробный гайд: DXE в контексте UEFI и загрузки компьютера - Часть 2

Вторая часть о DXE в UEFI: диспетчеризация, Depex, события, память, runtime, переменные, Secure Boot, отладка и ошибки прошивки.

2026.08.21                  


Подробный гайд: DXE в контексте UEFI и загрузки компьютера - Часть 2Подробный гайд: DXE в контексте UEFI и загрузки компьютера - Часть 2 Вторая часть статьи, продолжает тему DXE в UEFI и переходит от базовых понятий к более практическим механизмам: диспетчеризации, событиям, памяти, runtime, безопасности и отладке.


Перейти к Части 1


15. Архитектурные протоколы DXE

Архитектурные протоколы — это базовые интерфейсы, без которых платформа не может корректно перейти к следующим этапам загрузки. Их установка часто является обязательной для нормального завершения DXE и начала BDS.




К наиболее важным архитектурным протоколам обычно относятся:

- EFI_CPU_ARCH_PROTOCOL

Управление процессором: прерывания, кэш, флаги, базовые CPU-операции.

- EFI_TIMER_ARCH_PROTOCOL

Таймерный сервис, на котором строятся события и таймеры UEFI.

- EFI_METRONOME_ARCH_PROTOCOL

Источник тактов для коротких задержек и калибровки времени.

- EFI_VARIABLE_ARCH_PROTOCOL

Доступ к переменным UEFI.

- EFI_VARIABLE_WRITE_ARCH_PROTOCOL

Подтверждает, что платформа поддерживает запись переменных.

- EFI_RUNTIME_ARCH_PROTOCOL

Инфраструктура для runtime-драйверов и сервисов, доступных после загрузки ОС.

- EFI_SECURITY_ARCH_PROTOCOL

Базовая политика безопасности загрузки.

- EFI_SECURITY2_ARCH_PROTOCOL

Расширенный механизм проверки образов и безопасности.

- EFI_WATCHDOG_TIMER_ARCH_PROTOCOL

Watchdog-таймер, который может перезагрузить систему при зависании.

- EFI_RESET_ARCH_PROTOCOL

Механизм сброса системы.

- EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL

Доступ к часам реального времени.

- EFI_FIRMWARE_VOLUME2_PROTOCOL

Доступ к Firmware Volume, чтение файлов и секций.

- EFI_DEVICE_PATH_PROTOCOL

Универсальное описание путей к устройствам.

- EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

Распределение ресурсов для PCI/PCIe при инициализации шины.


Важно понимать:

DXE Dispatcher внимательно следит за появлением таких протоколов. Если один из критичных архитектурных протоколов не установлен, зависимые драйверы могут так и не запуститься, а система зависнет на этапе DXE или не перейдёт к BDS.


16. DXE Dispatcher изнутри

DXE Dispatcher — это не просто загрузчик модулей, а механизм управления зависимостями и порядком инициализации.

Его работу можно описать так:

1. Поиск Firmware Volumes

DXE Core узнаёт, какие Firmware Volumes доступны: из HOB, через протоколы или через вложенные образы.

2. Сканирование файлов

Внутри каждого Firmware Volume Dispatcher ищет файлы подходящих типов: драйверы, приложения, вложенные FV.

3. Чтение Depex

Для каждого драйвера анализируется выражение зависимости.

4. Проверка условий

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

5. Загрузка образа

PE/COFF-образ загружается в память, выполняются релокации.

6. Запуск точки входа

Вызывается entry point драйвера.

7. Повторный цикл

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

Отдельно стоит упомянуть a priori file. Это специальный файл внутри Firmware Volume, который задаёт список драйверов для приоритетной загрузки. Он не заменяет Depex, но помогает жёстко задать порядок для критичных модулей.


Практический смысл a priori file:

  • сначала поднять переменные;
  • затем безопасность;
  • затем chipset-драйверы;
  • затем консоль;
  • затем ACPI и SMBIOS.

Если драйвер не запускается, Dispatcher обычно сохраняет информацию об этом. Повторная попытка возможна, если изменились условия, но полагаться на «само заработает» не стоит.


17. Depex на практике

Depex — один из главных инструментов управления запуском DXE-драйверов.

Простейшие случаи

Запуск без условий:

[Depex]
  TRUE

Запрет запуска:

[Depex]
  FALSE

Запуск только при наличии протокола:

[Depex]
  gEfiPciRootBridgeIoProtocolGuid

Логические условия

Несколько протоколов:

[Depex]
  gEfiPciRootBridgeIoProtocolGuid AND gEfiVariableArchProtocolGuid

Альтернатива:

[Depex]
  gEfiSomeProtocolGuid OR gEfiOtherProtocolGuid

Отрицание:

[Depex]
  NOT gEfiSomeProtocolGuid

Порядок запуска

Иногда нужно не просто дождаться протокола, а повлиять на порядок:



[Depex]
  BEFORE gEfiSomeDriverProtocolGuid

или:

[Depex]
  AFTER gEfiSomeDriverProtocolGuid

Такие конструкции полезны, если платформа требует строгой последовательности, но использовать их нужно аккуратно: они делают систему менее гибкой.

Типичные ошибки Depex

  1. Драйвер использует протокол, но не указывает его в Depex.
  2. Depex слишком жёсткий и блокирует запуск на других платформах.
  3. Используется TRUE, хотя драйвер реально зависит от нескольких сервисов.
  4. Драйвер рассчитывает на протокол, который появляется только в BDS.
  5. Применяется BEFORE/AFTER без реальной необходимости.

Хорошее правило:

если драйвер не может работать без протокола — этот протокол должен быть в Depex.


18. События, таймеры и уведомления в DXE

DXE — событийно-ориентированная среда. Вместо «спящих» циклов и бесконечного ожидания используются события.

Основные механизмы:

  • создание событий;
  • ожидание событий;
  • проверка события;
  • таймеры;
  • уведомления о появлении протоколов;
  • уведомления о завершении boot services.

Создание события

Пример создания события по GUID:

EFI_EVENT Event;

Status = gBS->CreateEventEx (
                EVT_NOTIFY_SIGNAL,
                TPL_NOTIFY,
                MyNotifyFunction,
                NULL,
                &gEfiEventExitBootServicesGuid,
                &Event
                );

Такое событие может использоваться, например, для корректного завершения работы перед ExitBootServices.

Таймеры

Таймер создаётся через событие и SetTimer:

Status = gBS->SetTimer (
                TimerEvent,
                TimerPeriodic,
                TIMER_INTERVAL
                );

Варианты:

  • одноразовый таймер;
  • периодический таймер;
  • относительный таймер;
  • абсолютный таймер.

Protocol Notify

Если нужно дождаться появления протокола, лучше использовать protocol notify, а не опрос в цикле.

В EDK II часто применяют:

EfiCreateProtocolNotifyEvent (
  &gEfiSomeProtocolGuid,
  TPL_CALLBACK,
  MyProtocolNotify,
  NULL,
  &Registration
);

Это намного корректнее, чем делать LocateProtocol в бесконечном цикле.


19. TPL: уровни приоритета и безопасная обработка

TPL — Task Priority Level. Это механизм приоритетов в UEFI, который помогает управлять тем, когда могут выполняться события и обработчики.

Основные уровни:

  • TPL_APPLICATION
  • TPL_CALLBACK
  • TPL_NOTIFY
  • TPL_HIGH_LEVEL

Смысл TPL:

  • код с более высоким TPL временно блокирует события с более низким приоритетом;
  • обработчики не должны выполняться слишком долго;
  • нельзя бесконечно удерживать высокий приоритет;
  • события должны быть короткими и предсказуемыми.

Пример повышения приоритета:

EFI_TPL OldTpl;

OldTpl = gBS->RaiseTPL (TPL_NOTIFY);

// критичный участок

gBS->RestoreTPL (OldTpl);

Практическое правило

  • для большинства уведомлений подходит TPL_CALLBACK;
  • для важных системных уведомлений используют TPL_NOTIFY;
  • TPL_HIGH_LEVEL следует применять только в действительно критичных местах.

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


20. Работа с памятью в DXE

DXE активно использует сервисы памяти UEFI.

Основные операции:

  • AllocatePages
  • FreePages
  • AllocatePool
  • FreePool
  • GetMemoryMap

Типы памяти

Очень важно правильно выбирать тип памяти.

Часто используемые типы:

  • EfiBootServicesCode — код, нужный только до загрузки ОС;
  • EfiBootServicesData — данные, нужные только до загрузки ОС;
  • EfiRuntimeServicesCode — runtime-код;
  • EfiRuntimeServicesData — runtime-данные;
  • EfiACPIReclaimMemory — ACPI-данные, которые ОС может освободить после прочтения;
  • EfiACPIMemoryNVS — память, которая должна сохраняться;
  • EfiReservedMemoryType — зарезервированная область.


Почему это важно

После ExitBootServices операционная система получает memory map.
Если вы ошиблись с типом памяти, ОС может освободить или перезаписать область, которая всё ещё нужна firmware.

Например:

  • если runtime-структура лежит в EfiBootServicesData, она может быть потеряна;
  • если ACPI-таблицы размещены неправильно, ОС может их не увидеть;
  • если S3-данные размещены неверно, восстановление из сна может сломаться.

Memory Map и Map Key

Перед ExitBootServices загрузчик ОС вызывает GetMemoryMap и получает MapKey. Если после этого memory map меняется, ExitBootServices может завершиться ошибкой. Тогда загрузчик должен получить новую карту и повторить попытку.

Для DXE-разработчика это означает:

нельзя без необходимости менять memory map в самый последний момент.


21. DXE_RUNTIME_DRIVER: жизнь после ExitBootServices

Если модуль должен продолжать работать после загрузки ОС, его оформляют как runtime-драйвер.

В INF это обычно:

MODULE_TYPE = DXE_RUNTIME_DRIVER

Что важно понимать

После ExitBootServices:

  • Boot Services больше недоступны;
  • нельзя использовать LocateProtocol;
  • нельзя создавать обычные события через boot services;
  • нельзя полагаться на boot-память;
  • доступны только Runtime Services.

Virtual Address Change

Операционная система может вызвать SetVirtualAddressMap, чтобы перевести firmware-указатели в виртуальное адресное пространство. Runtime-драйвер должен корректно обработать это событие.

Пример регистрации события:

Status = gBS->CreateEventEx (
                EVT_NOTIFY_SIGNAL,
                TPL_NOTIFY,
                VirtualAddressChangeCallback,
                NULL,
                &gEfiEventVirtualAddressChangeGuid,
                &mVirtualAddressChangeEvent
                );

Внутри обработчика обычно вызывают преобразование указателей:

EfiConvertPointer (0, (VOID **)&MyPointer);

Частые ошибки runtime-драйверов

  1. Использование Boot Services после ExitBootServices.
  2. Хранение данных в памяти неправильного типа.
  3. Отсутствие обработки смены виртуальных адресов.
  4. Попытка использовать протоколы, которые не рассчитаны на runtime.
  5. Слишком сложная логика внутри runtime-обработчиков.

Runtime-код должен быть максимально простым, надёжным и предсказуемым.


22. Переменные UEFI: от инициализации до защищённой записи

Переменные UEFI — один из главных механизмов сохранения состояния платформы между перезагрузками.

Основные сервисы:

GetVariable
SetVariable
GetNextVariableName
QueryVariableInfo

Атрибуты переменных

Пример базовых атрибутов:

  • EFI_VARIABLE_NON_VOLATILE
  • EFI_VARIABLE_BOOTSERVICE_ACCESS
  • EFI_VARIABLE_RUNTIME_ACCESS
  • EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS

Пример установки переменной:

Status = gRT->SetVariable (
                L"MyVar",
                &gMyVendorGuid,
                EFI_VARIABLE_NON_VOLATILE |
                EFI_VARIABLE_BOOTSERVICE_ACCESS |
                EFI_VARIABLE_RUNTIME_ACCESS,
                sizeof (Data),
                &Data
                );

Где живут переменные

В зависимости от платформы переменные могут храниться в:

  • SPI-flash;
  • отдельной NVRAM-области;
  • энергонезависимой памяти контроллера;
  • защищённой области, обрабатываемой SMM.

Безопасные переменные

Для Secure Boot используются authenticated variables:

  • PK
  • KEK
  • db
  • dbx

Их изменение требует соблюдения политики безопасности. Просто так перезаписать ключи из обычного кода нельзя.



На практике запись таких переменных часто проходит через:

  • проверку подписи;
  • проверку прав;
  • SMM-обработчик;
  • защищённое хранилище;
  • механизм FTW для атомарности.

Variable Policy

В современных EDK II-платформах часто есть дополнительная политика переменных, которая может:

  • запрещать создание некоторых переменных;
  • ограничивать размер;
  • требовать авторизацию;
  • блокировать изменение после определённого этапа загрузки.

23. Secure Boot в DXE

Secure Boot — это политика доверия к загружаемым образам.

В DXE он опирается на:

  • сервис переменных;
  • Security Architecture Protocol;
  • Security2 Architecture Protocol;
  • проверку PE/COFF-образов;
  • базы ключей и хэшей.

Основные объекты

- PK — Platform Key

Корень доверия для управления ключами.

- KEK — Key Exchange Key

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

- db — Signature Database

Разрешённые подписи и хэши.

- dbx — Forbidden Signature Database

Запрещённые подписи и хэши.


Как происходит проверка

Упрощённо:

  1. BDS или другой код вызывает загрузку образа.
  2. Перед запуском срабатывает security-механизм.
  3. Образ проверяется по db и dbx.
  4. Если проверка успешна — образ разрешается.
  5. Если нет — возвращается ошибка безопасности.

Типичный статус:

EFI_SECURITY_VIOLATION

Что проверяется

Могут проверяться:

  • загрузчики ОС;
  • UEFI-приложения;
  • UEFI-драйверы;
  • option ROM;
  • capsule-образы;
  • некоторые recovery-компоненты.

Точная политика зависит от реализации платформы.

Практический вывод

Если вы разрабатываете собственный DXE-драйвер или загрузчик, вам нужно:

  • либо подписать образ;
  • либо добавить его хэш в db;
  • либо отключить Secure Boot на этапе разработки.

24. Measured Boot, TPM и журнал событий

Measured Boot и Secure Boot — разные вещи.

  • Secure Boot решает, можно ли выполнять образ.
  • Measured Boot решает, что факт выполнения образа нужно зафиксировать.

Если включён measured boot, платформа измеряет важные этапы загрузки и записывает результаты в TPM.

Что может измеряться

  • firmware-образ;
  • PEI-модули;
  • DXE-драйверы;
  • option ROM;
  • загрузчик;
  • параметры конфигурации;
  • ключевые переменные.

PCR

Результаты измерений обычно расширяются в регистрах TPM — PCR.

Типично:

  • PCR0 — базовый firmware;
  • PCR2 — option ROM и расширение платформы;
  • PCR4 — загрузчик;
  • другие PCR — дополнительные события.

Набор PCR и их назначение зависят от платформы и политики TCG.


Event Log

Кроме самих PCR, обычно ведётся журнал событий — TPM Event Log.

В нём можно посмотреть:

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

Этот журнал затем может использоваться для attestation — проверки состояния платформы.


25. PCI(e), Option ROM и UEFI Driver Model

Инициализация PCI/PCIe — одна из самых заметных задач DXE.

Основные участники

- PCI Root Bridge Driver

Предоставляет доступ к корневому мосту.

- PCI Bus Driver

Выполняет перечисление устройств.

- PCI Host Bridge Resource Allocation Protocol

Управляет ресурсами.

- EFI_PCI_IO_PROTOCOL

Интерфейс доступа к конкретному PCI-устройству.

- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL

Доступ к PCI-пространству через root bridge.


Что делает PCI Bus Driver

  • сканирует шины;
  • назначает bus number;
  • распределяет BAR;
  • включает device;
  • создаёт handle для устройств;
  • устанавливает PCI I/O Protocol;
  • подключает драйверы;
  • при необходимости загружает UEFI Option ROM.

Option ROM

Option ROM — это firmware-образ, расположенный на плате расширения.



Он может содержать:

  • legacy BIOS-код;
  • UEFI-драйвер;
  • оба варианта сразу.

В современном UEFI-режиме нас интересует прежде всего UEFI-часть.

Перед выполнением UEFI Option ROM платформа может проверить:

  • подпись;
  • хэш;
  • политику Secure Boot;
  • допустимость выполнения.

Если платформа запрещает неподписанные option ROM, устройство может не появиться до загрузки ОС.


26. Накопители: Block I/O, Partition и файловые системы

Чтобы загрузить ОС, firmware должна уметь работать с накопителями.

Основные уровни

Host Controller Driver
    ↓
Device Driver
    ↓
EFI_BLOCK_IO_PROTOCOL
    ↓
Partition Driver
    ↓
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL

Block I/O

EFI_BLOCK_IO_PROTOCOL даёт поблочный доступ к устройству:

  • чтение блоков;
  • запись блоков;
  • получение информации о носителе;
  • сброс устройства;
  • обработка смены носителя.

Disk I/O

EFI_DISK_IO_PROTOCOL позволяет читать и писать байтовые диапазоны поверх блочного устройства.


Partition Driver

Он распознаёт:

  • GPT;
  • MBR;
  • El Torito;
  • другие схемы, если реализованы.

После этого создаются дочерние handle для разделов.


Файловые системы

Для UEFI чаще всего важна FAT-файловая система, потому что EFI System Partition обычно использует FAT.

Через EFI_SIMPLE_FILE_SYSTEM_PROTOCOL можно:

  • открыть том;
  • открыть файл;
  • прочитать файл;
  • записать файл;
  • получить информацию о файле.

Практический смысл

Для загрузки ОС firmware должна дойти до состояния, когда:

  • контроллер накопителя инициализирован;
  • раздел найден;
  • файловая система доступна;
  • загрузочный файл можно прочитать и запустить.

27. Консоль и графика: GOP, ConOut и boot logo

Пользователь видит результат работы DXE и BDS через консоль и графику.

Основные протоколы

- EFI_SIMPLE_TEXT_INPUT_PROTOCOL

Ввод с клавиатуры.

- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL

Текстовый вывод.

- EFI_GRAPHICS_OUTPUT_PROTOCOL

Графический framebuffer.


GOP

GOP заменяет старые видеорежимы и предоставляет:

  • разрешение;
  • формат пикселя;
  • адрес framebuffer;
  • режимы отображения.

Именно GOP часто используется для:

  • логотипа загрузки;
  • простого boot splash;
  • текстового вывода;
  • раннего отображения до запуска видеодрайвера ОС.

ConIn, ConOut, ErrOut

В UEFI есть переменные:

  • ConIn
  • ConOut
  • ErrOut

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

Платформа может, например, переключить консоль между:

  • serial-портом;
  • USB-клавиатурой;
  • встроенным дисплеем;
  • внешним GPU;
  • виртуальной консолью.

Почему это важно для DXE

Если консоль не инициализирована вовремя:

  • не будет видно setup-меню;
  • не отобразятся ошибки;
  • boot-меню может зависнуть;
  • пользователь решит, что система не отвечает.

28. Сеть в DXE: PXE, HTTP Boot и Load File

DXE может реализовать полноценный сетевой стек.

Уровни сетевого стека

Типичная структура:

Network Controller
    ↓
SNP
    ↓
MNP
    ↓
ARP / IP4 / IP6
    ↓
UDP / TCP
    ↓
DHCP
    ↓
TFTP / HTTP Boot
    ↓
Load File Protocol

Основные протоколы

  • SNP — Simple Network Protocol
  • MNP — Managed Network Protocol
  • ARP
  • IP4 / IP6
  • UDP / TCP
  • DHCP4 / DHCP6
  • HTTP / TLS
  • PXE / TFTP
  • Load File Protocol

Как происходит сетевая загрузка

  1. BDS выбирает сетевую загрузочную запись.
  2. Сетевой контроллер подключается.
  3. Выполняется DHCP или автоконфигурация.
  4. Получается адрес загрузчика.
  5. Образ скачивается.
  6. Загрузчик запускается.

Практическая деталь

Сетевой стек — один из самых тяжёлых компонентов DXE.
Если сетевая загрузка не нужна, её часто отключают для ускорения boot и уменьшения поверхности атаки.


29. Типичные ошибки и диагностика DXE-модулей



DXE-ошибки часто проявляются как «зависание до ОС», «нет дисков», «не работает консоль» или «Secure Boot violation». Ниже — типовые проблемы.

Драйвер не запускается

Причины:

  • модуль не добавлен в FDF;
  • драйвер не попал в нужный FV;
  • Depex не выполняется;
  • нет нужного протокола;
  • entry point вернул ошибку;
  • неверный MODULE_TYPE.

Что проверять:

  • firmware-образ;
  • debug-лог;
  • секцию [Depex];
  • наличие протокола в системе;
  • статус точки входа.

Драйвер запускается, но протокол не появляется

Причины:

  • ошибка внутри драйвера;
  • протокол устанавливается на неправильный handle;
  • установка протокола завершилась ошибкой;
  • драйвер ожидал ресурсы, которых нет.

Что проверять:

  • статус InstallProtocolInterface;
  • корректность handle;
  • наличие зависимостей;
  • порядок запуска.

Система зависает после инициализации устройства

Причины:

  • бесконечный цикл;
  • долгий опрос устройства;
  • конфликт драйверов;
  • устройство не отвечает;
  • неверная работа с прерываниями.

Что проверять:

  • таймауты;
  • debug-печать;
  • watchdog;
  • статусы операций;
  • поведение на другом железе.

Ошибка Secure Boot

Причины:

  • неподписанный образ;
  • хэш отсутствует в db;
  • образ в dbx;
  • нарушена политика загрузки.

Что проверять:

  • состояние Secure Boot;
  • SetupMode;
  • db и dbx;
  • подпись образа;
  • журнал measured boot, если доступен.

Переменная не читается из ОС

Причины:

  • неверные атрибуты;
  • переменная не была сохранена как non-volatile;
  • нет runtime-доступа;
  • переменная удалена политикой;
  • NVRAM повреждена.

Что проверять:

  • атрибуты SetVariable;
  • GUID переменной;
  • наличие EFI_VARIABLE_RUNTIME_ACCESS;
  • размер данных;
  • логи firmware.

30. Чек-лист разработчика DXE

Ниже — практический чек-лист, который помогает избежать большинства типовых ошибок.

Базовая структура модуля

  • [ ] Правильный MODULE_TYPE
  • [ ] Уникальный FILE_GUID
  • [ ] Корректный ENTRY_POINT
  • [ ] Модуль добавлен в DSC
  • [ ] Модуль добавлен в FDF
  • [ ] Все библиотеки разрешены в DSC
  • [ ] Протоколы и GUID объявлены в INF

Depex

  • [ ] Драйвер зависит только от реально нужных протоколов
  • [ ] Нет скрытых зависимостей
  • [ ] Нет лишнего TRUE, если нужны протоколы
  • [ ] BEFORE/AFTER используется осознанно
  • [ ] Порядок запуска не ломает другие платформы

События и таймеры

  • [ ] Нет бесконечных циклов ожидания
  • [ ] Используются события вместо busy wait
  • [ ] Обработчики короткие
  • [ ] TPL выбран адекватно
  • [ ] Таймеры корректно останавливаются

Память

  • [ ] Тип памяти соответствует времени жизни данных
  • [ ] Runtime-данные не лежат в boot memory
  • [ ] Нет утечек памяти
  • [ ] Указатели проверяются перед использованием
  • [ ] Буферы имеют правильный размер

Runtime

  • [ ] Модуль не использует Boot Services после ExitBootServices
  • [ ] Обработчик Virtual Address Change реализован
  • [ ] Все указатели преобразуются корректно
  • [ ] Runtime-память выделена правильно
  • [ ] Логика минимальна и надёжна

Переменные

  • [ ] Указаны правильные атрибуты
  • [ ] Non-volatile переменные действительно сохраняются
  • [ ] GUID уникален
  • [ ] Размер данных контролируется
  • [ ] Обработка ошибок SetVariable/GetVariable присутствует

Безопасность

  • [ ] Образ подписан или хэш добавлен в db
  • [ ] Нет обхода Secure Boot в debug-режиме без необходимости
  • [ ] Входные данные проверяются
  • [ ] Нет небезопасных строковых операций
  • [ ] Чувствительные данные не пишутся в debug-лог
  • [ ] SMM-границы не нарушаются

Отладка

  • [ ] Есть debug-печать на ключевых этапах
  • [ ] Проверяются все статусы
  • [ ] Используются коды ошибок
  • [ ] Можно получить serial/debug log
  • [ ] Есть возможность проверить handle database через shell
  • [ ] Есть возможность проверить переменные и протоколы

Итог второй части

Во второй части мы разобрали DXE уже как рабочую инженерную среду:

  • как устроены архитектурные протоколы;
  • как DXE Dispatcher принимает решения о запуске драйверов;
  • как писать корректные Depex;
  • как работают события, таймеры и TPL;
  • как правильно обращаться с памятью;
  • чем отличаются runtime-драйверы;
  • как устроены переменные, Secure Boot и measured boot;
  • как DXE работает с PCI, накопителями, графикой и сетью;
  • какие ошибки встречаются чаще всего и как их диагностировать.

Если первая часть объясняла что такое DXE и зачем он нужен, то вторая часть показывает как DXE реально работает изнутри и на что смотреть при разработке и отладке.


Перейти к Части 1


Мы делимся этой технической информацией, чтобы помочь вам в решении задач — используйте её с пониманием. Статья носит рекомендательный характер, поэтому, пожалуйста, применяйте описанные методы осмотрительно.


Статью подготовил: Аверко Денис Сергеевич @Nymexis г. Омск (специалист по ЗИ)

Комментарии

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