On Jul 2, 2014, at 2:49 AM, Gurinder Singh <frederick.the.f...@gmail.com> wrote:
> Hi guys,
>
>
> I’m writing a small EFI shim that will load the Windows UEFI loader
> bootmgfw.efi and run it. Here’s the relevant code snippet:
>
>
>
>
> bootProgramName = "boot\\x64\\bootmgfw.efi";
>
>
> // Get the size of bootmgfw.efi from the TFTP server
>
> status = pxeProtocol->Mtftp(pxeProtocol,
> EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE, NULL, FALSE, &bootProgramSize,
> &tftpBlockSize, &bootServerIp, bootProgramName, NULL, FALSE);
>
>
> // Allocate buffer and download bootmgfw.efi
>
> bootProgramBuffer = AllocatePool(bootProgramSize);
>
> status = pxeProtocol->Mtftp(pxeProtocol, EFI_PXE_BASE_CODE_TFTP_READ_FILE,
> bootProgramBuffer, FALSE, &bootProgramSize, &tftpBlockSize, &bootServerIp,
> bootProgramName, NULL, FALSE);
>
>
> // Load it as an image
>
> status = gBS->LoadImage(FALSE, NULL, NULL, bootProgramBuffer,
> bootProgramSize, &loadedBootProgram);
>
>
What return status do you get here? Is loadedBootProgram a valid handle? It
should have the LoadedImage protocol on the handle. You can dump that out for
more info.
https://svn.code.sf.net/p/edk2/code/trunk/edk2/MdePkg/Include/Protocol/LoadedImage.h
typedef struct {
UINT32 Revision; ///< Defines the revision of the
EFI_LOADED_IMAGE_PROTOCOL structure.
///< All future revisions will be backward
compatible to the current revision.
EFI_HANDLE ParentHandle; ///< Parent image's image handle. NULL if
the image is loaded directly from
///< the firmware's boot manager.
EFI_SYSTEM_TABLE *SystemTable; ///< the image's EFI system table pointer.
//
// Source location of image
//
EFI_HANDLE DeviceHandle; ///< The device handle that the EFI Image
was loaded from.
EFI_DEVICE_PATH_PROTOCOL *FilePath; ///< A pointer to the file path portion
specific to DeviceHandle
///< that the EFI Image was loaded
from.
VOID *Reserved; ///< Reserved. DO NOT USE.
//
// Images load options
//
UINT32 LoadOptionsSize;///< The size in bytes of LoadOptions.
VOID *LoadOptions; ///< A pointer to the image's binary load
options.
//
// Location of where image was loaded
//
VOID *ImageBase; ///< The base address at which the image
was loaded.
UINT64 ImageSize; ///< The size in bytes of the loaded image.
EFI_MEMORY_TYPE ImageCodeType; ///< The memory type that the code sections
were loaded as.
EFI_MEMORY_TYPE ImageDataType; ///< The memory type that the data sections
were loaded as.
EFI_IMAGE_UNLOAD Unload;
} EFI_LOADED_IMAGE_PROTOCOL;
> FreePool(bootProgramBuffer);
>
>
> // And start it.
>
> status = gBS->StartImage(loadedBootProgram, NULL, NULL); <--- This call
> returns status 2 (EFI_INVALID_PARAMETER)
>
>
>
gBS->StartImage maps to CoreStartImage()...
https://svn.code.sf.net/p/edk2/code/trunk/edk2/MdeModulePkg/Core/Dxe/Image/Image.c
EFI_STATUS
EFIAPI
CoreStartImage (
IN EFI_HANDLE ImageHandle,
OUT UINTN *ExitDataSize,
OUT CHAR16 **ExitData OPTIONAL
)
{
EFI_STATUS Status;
LOADED_IMAGE_PRIVATE_DATA *Image;
LOADED_IMAGE_PRIVATE_DATA *LastImage;
UINT64 HandleDatabaseKey;
UINTN SetJumpFlag;
UINT64 Tick;
EFI_HANDLE Handle;
Tick = 0;
Handle = ImageHandle;
Image = CoreLoadedImageInfo (ImageHandle);
if (Image == NULL || Image->Started) {
return EFI_INVALID_PARAMETER;
}
if (EFI_ERROR (Image->LoadImageStatus)) {
return Image->LoadImageStatus;
}
The return status could also be coming from the PE/COFF image if you actually
started it.
>
>
> The shim downloads the bootmgfw.efi file correctly and successfully loads it
> with LoadImage(). However, when it tries to transfer control to it by calling
> StartImage() an EFI_INVALID_PARAMETER status is returned. As per UEFI
> documentation this status code means the image is not valid.
>
>
> I’ve tried to tweak the PE headers of this image (file alignment and all),
> but nothing has worked. I don’t know any other reason why the image can be
> invalid.
>
>
The gBS->LoadImage() does all the PE/COFF loading. So you should get an error
out of that.
You can DUMPBIN.EXE /ALL (or other sets of args) to dump the PE/COFF
> The shim successfully loads and starts other .efi files that I’ve created
> myself using EDK. So I can’t see what’s wrong with this code either.
>
>
> Also bootmgfw.efi runs successfully if it is directly downloaded by the
> machine firmware over PXE (without my shim being involved at all).
>
>
Will it run if you launch it from the shell?
Thanks,
Andrew Fish
> Could anyone please spot what I’m doing wrong in the above code and help me?
> Or, if anyone has previous experience with this Microsoft boot loader, is
> there something special about it that I'm missing?
>
>
>
> Thanks in advance.
>
>
> Here’s the relevant information about my environment:
>
>
>
> UEFI machine: a HyperV virtual machine.
>
> TOOL_CHAIN_TAG value: VS2012x86.
>
> Architecture I’m building this shim for: x64
>
> Architecture of bootmgfw.efi: x64
>
> My build command-line:
>
> cd /D D:\Projects\1E\tianocore-edk2
>
> set WORKSPACE=D:\Projects\1E\tianocore-edk2
>
> call edksetup.bat
>
> Build -a X64 -p DuetPkg/DuetPkgX64.dsc
>
>
>
> Cheers,
>
> Gurinder
>
> ------------------------------------------------------------------------------
> Open source business process management suite built on Java and Eclipse
> Turn processes into business applications with Bonita BPM Community Edition
> Quickly connect people, data, and systems into organized workflows
> Winner of BOSSIE, CODIE, OW2 and Gartner awards
> http://p.sf.net/sfu/Bonitasoft_______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/edk2-devel
------------------------------------------------------------------------------
Open source business process management suite built on Java and Eclipse
Turn processes into business applications with Bonita BPM Community Edition
Quickly connect people, data, and systems into organized workflows
Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel