I'm writing my own bootloader and I want to be able to boot Windows (and Linux).
bootmgfw.efi
is the windows bootloader and I'm trying to load and start it with UEFI functions LoadImage()
and StartImage()
, but after calling StartImage()
on it, I get EFI_INVALID_PARAMETER
error, even though I checked that the image handle is valid and LoadImage()
didn't return an error status.
I am able to start other EFI applications with the same code but bootmgfw.efi
is the only one that doesn't start, though I am able to start it in the UEFI Shell just fine.
Here is some context to show what I do. I'm using POSIX-UEFI to write my code.
// Opening the root volume
efi_handle_t device = LIP->DeviceHandle;
efi_simple_file_system_protocol_t* fsProtocol = NULL;
efi_guid_t fsGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
BS->OpenProtocol(device, &fsGuid, (void**)&fsProtocol, IM, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
efi_file_handle_t* rootDir = NULL;
fsProtocol->OpenVolume(fsProtocol, &rootDir);
// Opening the bootloader file
efi_file_handle_t* winBootMgrHandle = NULL;
uint16_t path[] = u"EFI\\Microsoft\\Boot\\bootmgfw.efi";
rootDir->Open(rootDir, &winBootMgrHandle, path, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY);
// Getting file info for the file size
efi_guid_t infoGuid = EFI_FILE_INFO_GUID;
efi_file_info_t fileInfo;
uintn_t infoSize = sizeof(fileInfo);
winBootMgrHandle->GetInfo(winBootMgrHandle, &infoGuid, &infoSize, &fileInfo);
// Reading the file into a buffer
uintn_t winBootMgrSize = fileInfo.FileSize;
char* winBootMgrData = (char*)malloc(winBootMgrSize + 1);
winBootMgrData[winBootMgrSize] = 0;
winBootMgrHandle->Read(winBootMgrHandle, &winBootMgrSize, winBootMgrData);
// Loading and starting the image
efi_handle_t imgHandle;
BS->LoadImage(0, IM, LIP->FilePath, winBootMgrData, winBootMgrSize, &imgHandle);
BS->StartImage(imgHandle, NULL, NULL); // returns -2: invalid parameter
I don't understand why I get this error and how it can be fixed. I want to know how to fix this error and start this windows bootloader.
I got the solution here. Turns out I really was passing the incorrect device path to LoadImage()
.
https://forum.osdev.org/viewtopic.php?f=1&t=50623