в примере спецификаций uefi упоминается EfiCoreImageHandle. Как его получить?

#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