Как правильно загрузить протокол UEFI?

Извините, если это не соответствует формату Stackru. В настоящее время я учусь писать приложения UEFI. Я читал стандарт UEFI, а также множество онлайн-учебников, и я не могу понять, каков правильный метод загрузки протокола UEFI. Все учебные пособия, похоже, отличаются в методе, который они используют.

Во многих случаях учебные пособия следуют методу определения дескриптора и последующей итерации по буферу дескриптора для открытия протокола. Пример показан ниже:

EFI_HANDLE *handle_buffer;
UINTN handle_count;
EFI_GRAPHICS_OUTPUT_PROTOCOL *protocol;

// GNU-EFI wrapper.
status = uefi_call_wrapper(gBS->LocateHandleBuffer,
    5,
    ByProtocol,
    &gEfiGraphicsOutputProtocolGuid,
    NULL,
    &handle_count,
    &handle_buffer);

UINTN i = 0;
for(i = 0; i < handle_count; i++) {
    status = uefi_call_wrapper(gBS->OpenProtocol, 6,
        handle_buffer[i],
        &gEfiGraphicsOutputProtocolGuid,
        (VOID **)&protocol,
        ImageHandle,                        // from `efi_main`
        NULL,
        EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);

    if(status == EFI_SUCCESS) {
        break;
    }
}

Кроме того, кажется, что вы можете просто загрузить протокол напрямую, используя LocateProtocol функция. Пример:

status = uefi_call_wrapper(gBS->LocateProtocol,
    3,
    &gEfiGraphicsOutputProtocolGuid,
    NULL,
    &graphics_service.protocol);

Оба приведенных выше примера работают. Я не уверен, что понимаю значение извлечения буфера дескриптора перед загрузкой протокола, как видно из некоторых уроков и онлайн-материалов. Из поиска примеров на Github, похоже, что оба они взаимозаменяемы, и до сих пор я нашел обе работы одинаково хорошо. Я понимаю, что в первом методе мне потребуется освободить буфер, так как он выделен из пула, тогда как во втором нет ответственности за это.

Кто-нибудь может указать, какой метод является идеальным для загрузки протокола UEFI? Есть ли проблемы с любым методом? Любая помощь здесь будет оценена.

1 ответ

Решение

Для этого конкретного случая (пытаясь найти "EFI_GRAPHICS_OUTPUT_PROTOCOL"), если есть только один, или вы хотите только один, и не важно, какой из них; тогда gBS->LocateProtocol это проще (и, возможно, быстрее?), но вы могли бы использовать gBS->LocateHandleBuffer тоже если хочешь.

Тем не мение; Что делать, если есть 5 видеокарт с 2 мониторами в каждой, и есть 10 разных экземпляров "EFI_GRAPHICS_OUTPUT_PROTOCOL"? В этом случае, может быть, вам нужны все из них (чтобы вы могли настроить хороший режим видео на всех 10 мониторах), и, возможно, вы хотите найти правильный (например, буквально тот, который находится справа от пользователя).) и пропустить / избежать других 9 неправильных. Для этого вы должны использовать gBS->LocateHandleBuffer,

Другие вопросы по тегам