如果这不符合StackOverflow格式,请表示歉意。我目前正在学习如何编写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协议的理想方法?这两种方法都有什么问题吗?这里的任何帮助都将不胜感激。
发布于 2019-08-14 05:37:58
对于这个特殊情况(试图找到"EFI_GRAPHICS_OUTPUT_PROTOCOL"),如果只有一个,或者您只想要一个,而不关心哪一个;那么gBS->LocateProtocol更容易(可能更快?)但如果你愿意的话,你也可以使用gBS->LocateHandleBuffer。
但是,如果有5个每张带有2个监视器的显卡,并且有10个不同的"EFI_GRAPHICS_OUTPUT_PROTOCOL“实例,该怎么办?在这种情况下,您可能需要所有这些(这样您就可以在所有10个监视器上设置一个很好的视频模式),或者您想要搜索正确的(例如,用户右边的那个)并跳过/避免其他9个错误的。为此,您必须使用gBS->LocateHandleBuffer。
https://stackoverflow.com/questions/57487924
复制相似问题