Using UEFI LoadImage

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Using UEFI LoadImage

Post by nexos »

Hello,
I am making an EFI bootloader, and ran into a problem. I am calling LoadImage to test chainloading, but it doesn't work. Here is how I call it:

Code: Select all

BS->LoadImage(FALSE, ImageHandle, loader->FilePath, buffer, size, &handle);
BS->StartImage(handle, 0, 0)
The Image starts fine, but then it runs the following code:

Code: Select all

EFI_GUID imageGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
status = BS->HandleProtocol(ImageHandle, &imageGuid, (VOID**)&loader);
EFI_GUID fsProt = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
status = BS->HandleProtocol(loader->DeviceHandle, &fsProt, (VOID**)&fileSys);
And the second call fails with EFI_ERROR_INVALID_PARAMETER.
Also, I am using the file handle obtained from the images structure.
Any suggestions?
Thanks,
nexos
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
zaval
Member
Member
Posts: 656
Joined: Fri Feb 17, 2017 4:01 pm
Location: Ukraine, Bachmut
Contact:

Re: Using UEFI LoadImage

Post by zaval »

Code: Select all

BS->LoadImage(FALSE, ImageHandle, loader->FilePath, buffer, size, &handle);
uhm, do you start the image recursively? because loader->FilePath points to the file part of the of the device path of the image, whose Loaded Image Protocol instance is pointed to by the "loader" variable.

Also, use OpenProtocol() instead of HandleProtocol() for obtaining a protocol instance from the handle, the latter is deprecated. I do like this and it works:

Code: Select all

	Status = pbs->OpenProtocol(
			gpLoadedImageProtocol->DeviceHandle,
			&gEfiSimpleFileSystemGuid,
			&gpSfspHomeDrive,
			ImageHandle,
			NULL,
			EFI_OPEN_PROTOCOL_GET_PROTOCOL
		);
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: Using UEFI LoadImage

Post by nexos »

I changed it to use OpenProtocol, and I also changed the LoadImage call to look like

Code: Select all

EFI_MEMORY_MAPPED_DEVICE* memDev = (EFI_MEMORY_MAPPED_DEVICE*)AllocMem(sizeof(EFI_MEMORY_MAPPED_DEVICE) * 2);
    memDev[0].Type = 1;
    memDev[0].subType = 3;
    memDev[0].len = 24;
    memDev[0].type = EfiLoaderData;
    memDev[0].startAddr = (UINT64)buffer;
    memDev[0].endAddr = (UINT64)buffer + size;
    memDev[1].Type = 0x7F;
    memDev[1].subType = 0xFF;
    memDev[1].len = 4;
    EFI_STATUS status = BS->LoadImage(FALSE, ImageHandle, (EFI_DEVICE_PATH_PROTOCOL*)memDev, buffer, size, &handle);
It does the same thing still.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: Using UEFI LoadImage

Post by nexos »

It appears I found something interesting. When I chainload the app, the DeviceHandle of that app is 0 for some reason. Will have to look into.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
zaval
Member
Member
Posts: 656
Joined: Fri Feb 17, 2017 4:01 pm
Location: Ukraine, Bachmut
Contact:

Re: Using UEFI LoadImage

Post by zaval »

when you LoadImage() something, it means, you have 2 images - one, that is started by the FW (let it be Img0) and the other (Img1), you start through LoadImage()/StartImage(). you should provide Device Path to Img1, when doing LoadImage() for it. So the Device Path would be something like [storage-device-part]\efi\nexos\Img1.efi. If Img1 resides on the same volume as Img0, [storage-device-part] is the same as for Img0. The idea is you should know the Device Path of this image (generally speaking, your chainloading system should have it written somewhere in its configuration). what do you try to accomplish with feeding LoadImage() with memory mapped device path? it won't let you grab Img1 from its storage. and btw, why do you start UEFI with such an unnecessary and useless thing like "chainloading"?
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).
Post Reply