#c #specifications #boot #bootloader #uefi
#c #спецификации #загрузка #загрузчик #uefi
Вопрос:
Цитирую раздел спецификаций UEFI о EFI_BOOT_SERVICES.HandleProtocol():
Функция HandleProtocol() по-прежнему доступна для использования старыми приложениями и драйверами EFI. Однако все новые приложения и драйверы должны использовать EFI_BOOT_SERVICES.OpenProtocol() вместо HandleProtocol(). Следующий фрагмент кода показывает возможную реализацию HandleProtocol() с использованием OpenProtocol(). Переменная EfiCoreImageHandle является дескриптором образа ядра EFI.
EFI_STATUS
HandleProtocol (
IN EFI_HANDLE Handle,
IN EFI_GUID *Protocol,
OUT VOID **Interface
)
{
return OpenProtocol (
Handle,
Protocol,
Interface,
EfiCoreImageHandle,
NULL,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
);
}
Конец цитаты.
Мой вопрос: как получить значение для EfiCoreImageHandle, когда приложение EFI было запущено менеджером загрузки или из оболочки UEFI?
Комментарии:
1. Я не думаю, что у приложения есть способ получить его; по крайней мере, не стандартный способ. Может быть способ для отладчика получить его. Я не думаю, что обычно приложению требуется его использовать. При вызове OpenProtocol вы должны передать свой собственный дескриптор изображения.
2. @prl, (1) Означает ли это, что вы считаете, что спецификации должны быть исправлены? Я цитировал спецификацию. Я думаю, что они должны быть авторитетными. (2) Предлагаете ли вы передавать одну и ту же переменную как в 4-й, так и в 1-й параметр? То есть, в случае примера, задайте для обработки как 1-й, так и 4-й параметры?
return OpenProtocol(Handle, Protocol, Interface, Handle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
3. Нет, я не думаю, что спецификация нуждается в исправлении. Я думаю, вы неправильно это понимаете. В нем говорится, что новые приложения не должны вызывать HandleProtocol. Вы должны вызвать OpenProtocol с вашим собственным дескриптором изображения. Но если старое приложение вызывает HandleProtocol, оно ведет себя так, как если бы OpenProtocol вызывался с показанными аргументами.
4. Первый параметр — это дескриптор, с помощью которого вы хотите открыть протокол. Четвертый параметр — это дескриптор изображения. Они будут одинаковыми, только если вы открываете протокол для дескриптора изображения (например, LoadedImageProtocol).
Ответ №1:
Проще говоря, EfiCoreImageHandle
это просто заполнитель в спецификации. Посмотрите, как я вызываю OpenProtocol
в ShowEDID
утилите в https://github.com/fpmurphy/UEFI-Utilities-2019.
Также посмотрите на ShowUSB
утилиту, которую я сейчас использую HandleProtocol
, т.Е.
Status = gBS->HandleProtocol( HandleBuffer[Index],
amp;gEfiUsbIoProtocolGuid,
(VOID**)amp;UsbIo );
Я мог бы заменить приведенный выше код на:
Status = gBS->OpenProtocol( HandleBuffer[Index],
amp;gEfiUsbIoProtocolGuid,
(VOID **)amp;UsbIo,
gImageHandle,
NULL,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );
Протестировано с UDK2018 и Lenovo T480