Вопрос, на который я хочу найти ответ:
Драйвер обязательно должен быть вместе с прочей прошивкой быть прошит в FLASH-память,
или его можно загрузить позднее из UEFI Shell? (Ну и разумеется не только загрузить, но и вызывать)
Если меня не обманывает память, то для старых машин, в которых ещё не было UEFI, а вместо этого был BIOS,
был написан проект, которые имитирует UEFI, т.е. из BIOS грузится заглушка-имитатор, которая запускает UEFI-Shell или другие UEFI-программы.
Как этот проект назывался?
LLM: «UEFI позволяет динамическую загрузку драйверов из внешних носителей (USB, HDD/SSD, сетевые ресурсы) через UEFI Shell, Boot Manager или загрузчики.»
«Динамическая загрузка драйверов в UEFI критична для поддержки новых устройств, сетевых загрузок, криптографии (Secure Boot) без обновления прошивки.»
«Проект, который эмулировал UEFI поверх BIOS для старых систем, — TianoCore EDK2 с DUET (Developer's UEFI Emulation).»
«DUET — это компонент EDK2, который создаёт виртуальную UEFI-среду внутри BIOS, позволяя запускать UEFI Shell, драйверы и загрузчики на машинах без нативной UEFI.»
«DUET позволял разработчикам тестировать UEFI-код на старых BIOS-системах, имитируя UEFI-окружение.»
В моём случае я хочу оформить компилятор как драйвер, чтобы воспользоваться UEFI Byte Code на платформе Arm64.
«SeaBIOS + OVMF — в виртуализации (QEMU/KVM) используется комбинация SeaBIOS для BIOS-эмуляции и OVMF (TianoCore) для UEFI.»
«Эту виртуалку реально добавляют в виде DXE‑драйвера — „EBC interpreter” от TianoCore.»
«На ARM64 производители прошивок чаще не тратят место в flash под него, потому что «все свои» пишут драйверы в nativе‑коде, и EBC, скажем прямо, сейчас мало кто использует.»
«EBC на ARM64 — экзотика. В BIOS‑классическом мире (x86) его использовали чтобы не городить драйвер каждый под x86 и x64 раздельно, а писать один. На ARM64 практически все делают нативные .efi под AArch64. Так что тебе может реально понадобиться «пилить дорогу мачете в джунглях», т.е. самостоятельно адаптировать интерпретатор.»
«потребуется EBC Interpreter DXE на ARM64. Его можно собрать из EDK2, но обычно он не входит в стандартную прошивку. Т.е. придётся его самому интегрировать и удостовериться, что он умеет выполняться на AArch64.»
«EBC на ARM64: готовься сам собирать интерпретатор, это не „из коробки”.»
«Если вы работаете с конкретной системой — проверьте, поддерживает ли её BIOS режим CSM (Compatibility Support Module), который может загружать UEFI-драйверы.»
«скомпилированные EBC‑модули загружаются Shell’ом или через Boot Manager как обычные исполняемые.»
«драйверы можно загрузить командой load в UEFI Shell. После загрузки они регистрируют свои протоколы/сервисы и могут использоваться как любой нативный драйвер.»
«EBC — интерпретируемый байт-код UEFI, предназначенный для простых, переносимых драйверов (например, для USB-устройств).»
«EBC-ограничения: Не поддерживает JIT, сложные оптимизации, доступ к низкоуровневым регистрам.»
«EBC не подходит для написания компиляторов: его производительность низкая, а стандартные библиотеки отсутствуют.»
«EBC выполняется через UEFI-интерпретатор, который на ARM64 может быть реализован, но не гарантирует стабильности для сложных программ.»
«Компилятор внутри драйвера — риск безопасности: он может выполнять произвольный код, что нарушает модель безопасности UEFI.»
«Secure Boot блокирует неподписанные/неверные драйверы. EBC-драйверы тоже должны быть подписаны, но их отладка сложнее.»
«Компилятор как драйвер — это анти-паттерн, который приведёт к проблемам с производительностью, безопасностью и поддержкой.»
«Пример: EBC-драйвер для простого устройства (например, светодиода).
Инструменты: EbcCompiler из EDK2, который переводит C-код в EBC.
Примеры EBC-драйверов в EDK2: MdeModulePkg/Universal/EbcDxe»
---
команда load запускает код на выполнение? Как происходит регистрация? Как интерфейс драйвера становится доступен другим программам?
«load mydriver.efi читает файл в оперативную память, проверяет заголовок (PE32+, EFI_IMAGE_HEADER).»
«Secure Boot проверяет подпись драйвера. Неподписанные — блокируются.»
«Загрузка модуля идёт через gBS->LoadImage() и gBS->StartImage(), т.е. это официальные сервисы UEFI Boot Services.»
«UEFI сразу вызывает EfiMain — главную функцию драйвера, это инициализация кода.»
```
EFI_STATUS EFIAPI UefiMain(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
```
«Если драйвер не вернёт EFI_SUCCESS, он не загрузится. Ошибки логируются в Shell.»
«Драйвер регистрирует протоколы (уникальные интерфейсы по GUID), которые становятся публичным API для всего UEFI-окружения.»
«Если драйвер не регистрирует протоколы или возвращает ошибку, он не будет доступен.»
«В EfiMain драйвер вызывает InstallProtocolInterface»
```
EFI_STATUS Status = gBS->InstallProtocolInterface(
&Handle, // Указатель на свой хэндл
&ProtocolGuid, // GUID вашего протокола
EFI_NATIVE_INTERFACE, // Тип интерфейса
&MyProtocolImplementation // Указатель на ваши функции
);
```
«Вызывает InstallProtocolInterface() или InstallMultipleProtocolInterfaces() — тем самым регистрирует новый протокол.»
«Если в UefiMain() был вызов InstallProtocolInterface(), драйвер закрепляется в системе.»
«Протоколы — это по сути структуры с функциями (vtable), C‑структура с указателями на callback’и.»
«у системы обновляется глобальный список времени выполнения „какие протоколы кто предоставляет”.»
«Драйвер должен реализовывать Unload — функцию для корректного выгрузки (освобождение памяти, закрытие хэндлов).»
«Что такое протокол? Структура с GUID-идентификатором и функциями (например, UsbIoProtocol для USB, BlockIoProtocol для дисков).»
«Другие драйверы и приложения ищут нужный протокол через LocateProtocol() или HandleProtocol().»
«Другое UEFI-приложение вызывает»
EFI_HANDLE* Handles; UINTN Count;
gBS->LocateHandleBuffer(ByProtocol, &MyCustomProtocolGuid, NULL, &Count, &Handles);
for (UINTN i=0; i<Count; i++) {
void* Interface;
gBS->OpenProtocol(Handles[i], &MyCustomProtocolGuid, &Interface, ...);
MyCustomProtocol* proto = (MyCustomProtocol*)Interface;
proto->DoSomething(); // Вызов вашей функции!
}
\^\^\^
В сообщении выше 5304 непробельных символа. Такой размер публикации на форуме OSSDEVCONF. Мало, не правда ли?
Отредактировано Лис (2025-10-01 04:39:58)