1

我基本上处于与以下完全相同的情况: UEFI Resolve full path

我遵循了他的解决方案,但EFI_NOT_FOUND在 LoadImage 方法中总是出错。

这是我的(质量差)代码...:

void BootLoaderStackoverflow(EFI_HANDLE ImageHandle) {
Print(L"BootLoaderStackoverflow - BEGIN\n");
EFI_STATUS status;
UINTN Event;
EFI_GUID vendor = EFI_GLOBAL_VARIABLE;
UINT32 Attr;

UINTN size = 256;
UINT16 *buf = AllocateZeroPool(size);
if (buf == NULL)
    Print(L"Failed to allocate buffer\n");

status = uefi_call_wrapper(RT->GetVariable, 5,
    L"BootOrder", /*VariableName*/
    &vendor, /*VendorGuid*/
    &Attr, /*Attributes*/
    &size, /*DataSize*/
    buf /*Data*/
);
if (status != EFI_SUCCESS)
    Print(L"Failed to read BootOrder (%d)\n", status);

// should contain an int for the correct boot option
UINT16 bootopt = buf[1];
FreePool(buf);

CHAR16 *name = AllocateZeroPool(18); // Bootxxxx\0 unicode
SPrint(name, 18, L"Boot%04x", bootopt);

Print(L"Next boot: %s\n", name);

size = 0;
do {
    buf = AllocateZeroPool(size);
    if (buf == NULL)
        Print(L"Failed to allocate buffer\n");

    status = uefi_call_wrapper(RT->GetVariable, 5,
        name,
        &vendor,
        &Attr,
        &size,
        buf
    );
    if (status == EFI_SUCCESS) break;

    FreePool(buf);
    // if it fails, size is set to what it needs to be
    // handy that
} while (status == EFI_BUFFER_TOO_SMALL);

Print(L"Description = %s\n", (CHAR16*)buf + 3);

UINT32 attributes = (UINT32)*buf;
UINT16 FilePathListLength = (UINT16)*((UINT8*)buf + sizeof(UINT32));
CHAR16* Description = (CHAR16*)buf + 3;
EFI_DEVICE_PATH *BootX = (EFI_DEVICE_PATH*)(((UINT8*)buf) + (sizeof(UINT32) + sizeof(UINT16) + StrSize(buf + 3)));
UINT8* OptionalData = (UINT8*)(BootX + FilePathListLength);
UINT8 OptionalDataLength = size - (sizeof(UINT32) + sizeof(UINT16) + StrSize(Description) + FilePathListLength);

Print(L"BootX = %s\n", DevicePathToStr(BootX)); // BootX = HD(Part1,....)..../\EFI\Microsoft\Boot\bootmgfw.efi

UINTN NoHandles = 0;
EFI_HANDLE *handles = NULL;
EFI_GUID SimpleFileSystemGUID = SIMPLE_FILE_SYSTEM_PROTOCOL;
status = uefi_call_wrapper(BS->LocateHandleBuffer,
    5,
    ByProtocol,
    &SimpleFileSystemGUID,
    NULL,
    &NoHandles,
    &handles
);
if (status != EFI_SUCCESS)
    Print(L"Failed to LocateHandleBuffer (%d)\n", status);
else
    Print(L"LocateHandleBuffer OK (%d handles)\n", NoHandles);

EFI_DEVICE_PATH *prefix;
UINTN index;
UINTN found = 0;
for (index = 0; index < NoHandles; index++) {
    prefix = DevicePathFromHandle(handles[index]); // PciRoot(0)/...../HD(Part2,....)
    Print(L"DevicePath[%d] = %s\n", index, DevicePathToStr(prefix));
    while (!IsDevicePathEnd(NextDevicePathNode(prefix))) {
        prefix = NextDevicePathNode(prefix); // until ==> prefix = HD(Part2,....)
    }
    if (LibMatchDevicePaths(prefix, BootX)) { // HD(Part2,...) != HD(Part1,...)
        found = 1;
        break;
    }
    else {
        FreePool(prefix);
    }
}

if (found == 1) {
    prefix = DevicePathFromHandle(handles[index]);

    // prefix ends with the same node that BootX starts with
    // so skip forward BootX so we can prepend prefix
    BootX = NextDevicePathNode(BootX);
    Print(L"BootX = %s\n", DevicePathToStr(BootX)); 

    EFI_DEVICE_PATH *fullpath = AppendDevicePath(prefix, BootX);
    FreePool(prefix);
    Print(L"Booting: %s\n", DevicePathToStr(fullpath));
    PrintPathNodes(fullpath);


    EFI_HANDLE *NextHandle = AllocateZeroPool(sizeof(EFI_HANDLE));

    /* EFI_STATUS (EFIAPI *EFI_IMAGE_LOAD) (
    IN BOOLEAN BootPolicy,
    IN EFI_HANDLE ParentImageHandle,
    IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
    IN VOID *SourceBuffer OPTIONAL,
    IN UINTN SourceSize,
    OUT EFI_HANDLE *ImageHandle
    ); */

    status = BS->LoadImage(TRUE, ImageHandle, fullpath, NULL, 0, NextHandle);

    //status = uefi_call_wrapper(BS->LoadImage, 6,
    //  /* status = BS->LoadImage( */
    //  TRUE, /* BootPolicy */
    //  ImageHandle, /* ParentImageHandle */
    //  fullpath, /* DevicePath */
    //  NULL, /* SourceBuffer */
    //  0, /* SourceSize */
    //  NextHandle /* ImageHandle */
    //);

    if (status != EFI_SUCCESS)
        Print(L"Failed to LoadImage (%r)\n", status);
    else
        Print(L"LoadImage OK\n");
}
else {
    Print(L"DevicePath matching BOOTX Not found\n");
}

Print(L"BootLoaderStackoverflow - END\n");
uefi_call_wrapper(ST->ConIn->Reset, 2, ST->ConIn, FALSE);
uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &Event);

}

完整路径是:PciRoot(0)/Pci(0x1D,0x2)/Pci(0x0,0x0)/Path(131,23,0x01000000002538B771B549D984012C00)/HD(Part2,SigD1377E10-FFDE-4CFB-B28D-D78CFDA52ECD)/\EFI\Microsoft\Boot\bootmgfw.efi

对我来说看起来不错...

这是我在屏幕上看到的:

这是我在屏幕上看到的

我错过了什么?加载一些驱动程序或协议?如您所见,我是 UEFI 开发的新手...

4

0 回答 0