Loading EFI module from disk and handing over execution


Andy Pont <andy.pont@...>
 

I am currently working on a project using tianocore as a payload for coreboot and have having some problems booting Qubes.

When trying to boot the Qubes ISO image from a USB memory stick it gives the error "Xen must be loaded below 4Gb". Looking at the Xen sources it is making two checks using the ImageBase and ImageSize values in the EFI_LOADED_IMAGE structure. The check that is failing that generates the error is that ((ImageBase + ImageSize) >> 32) isn't 0.

I'm struggling to find the right part of the tianocore sources to see where Xen's \EFI\BOOT\BOOTX64.EFI file is read from the USB stick to be able to see where, and how, ImageBase is setup.

Can anyone point me roughly in the right direction?

-Andy.


Laszlo Ersek
 

On 07/02/21 12:50, Andy Pont wrote:
I am currently working on a project using tianocore as a payload for coreboot and have having some problems booting Qubes.

When trying to boot the Qubes ISO image from a USB memory stick it gives the error "Xen must be loaded below 4Gb". Looking at the Xen sources it is making two checks using the ImageBase and ImageSize values in the EFI_LOADED_IMAGE structure. The check that is failing that generates the error is that ((ImageBase + ImageSize) >> 32) isn't 0.

I'm struggling to find the right part of the tianocore sources to see where Xen's \EFI\BOOT\BOOTX64.EFI file is read from the USB stick to be able to see where, and how, ImageBase is setup.

Can anyone point me roughly in the right direction?
I expected the UefiPayloadPkg owners to comment on this.

The inner half of your call chain is probably EfiBootManagerBoot()
[MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c]. You'll see
gBS->LoadImage() and gBS->StartImage() calls there. Those are
implemented as CoreLoadImage() [MdeModulePkg/Core/Dxe/Image/Image.c] and
CoreStartImage() [MdeModulePkg/Core/Dxe/Image/Image.c], respectively.

The outer half of your call chain is likely somewhere in
"UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c",
or in "MdeModulePkg/Universal/BdsDxe/BdsEntry.c".

Laszlo


Andy Pont <andy.pont@...>
 

Hi Laszlo,

The inner half of your call chain is probably EfiBootManagerBoot()
[MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c]. You'll see
gBS->LoadImage() and gBS->StartImage() calls there. Those are
implemented as CoreLoadImage() [MdeModulePkg/Core/Dxe/Image/Image.c] and
CoreStartImage() [MdeModulePkg/Core/Dxe/Image/Image.c], respectively.
I’ve been poking around in MdeModulePkg/Core/Dxe/Image/Image.c to see what is going on with the loading of the file and have got to the CoreLoadPeImage() function.

The memory that is being allocated for Xen’s \EFI\BOOT\BOOTX64.EFI to be loaded into is as a result of:

if (EFI_ERROR (Status) && !Image->ImageContext.RelocationsStripped) {
Status = CoreAllocatePages (
AllocateAnyPages,
(EFI_MEMORY_TYPE) (Image->ImageContext.ImageCodeMemoryType),
Image->NumberOfPages,
&Image->ImageContext.ImageAddress
);
}

The ImageAddress being returned by CoreAllocatePages() is 0x45D3A8000.
Looking in MdeModulePkg/Core/Dxe/Mem/Page.c the call sequence seems to be CoreAllocatePages() -> CoreInternalAllocatePages() -> FindFreePages() -> CoreFindFreePagesI( ).

Somewhere around that point, I have got a bit lost as I can’t work out which if the calls to CoreFindFreePagesI() is successful to figure out which bin the memory is being allocated from.

Is the address being used based on information EDK2 has worked out for itself or is it based on setup that coreboot has already done? What I’m trying to do is find a way to make it allocate memory below 4GB.

-Andy.


Laszlo Ersek
 

On 07/07/21 12:20, Andy Pont wrote:
Hi Laszlo,

The inner half of your call chain is probably EfiBootManagerBoot()
[MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c]. You'll see
gBS->LoadImage() and gBS->StartImage() calls there. Those are
implemented as CoreLoadImage() [MdeModulePkg/Core/Dxe/Image/Image.c] and
CoreStartImage() [MdeModulePkg/Core/Dxe/Image/Image.c], respectively.
I’ve been poking around in MdeModulePkg/Core/Dxe/Image/Image.c to see
what is going on with the loading of the file and have got to the
CoreLoadPeImage() function.

The memory that is being allocated for Xen’s \EFI\BOOT\BOOTX64.EFI to be
loaded into is as a result of:

      if (EFI_ERROR (Status) && !Image->ImageContext.RelocationsStripped) {
        Status = CoreAllocatePages (
                   AllocateAnyPages,
                   (EFI_MEMORY_TYPE)
(Image->ImageContext.ImageCodeMemoryType),
                   Image->NumberOfPages,
                   &Image->ImageContext.ImageAddress
                   );
      }

The ImageAddress being returned by CoreAllocatePages() is 0x45D3A8000. 
Looking in MdeModulePkg/Core/Dxe/Mem/Page.c the call sequence seems to
be CoreAllocatePages() -> CoreInternalAllocatePages() -> FindFreePages()
-> CoreFindFreePagesI( ).

Somewhere around that point, I have got a bit lost as I can’t work out
which if the calls to CoreFindFreePagesI() is successful to figure out
which bin the memory is being allocated from.

Is the address being used based on information EDK2 has worked out for
itself or is it based on setup that coreboot has already done?  What I’m
trying to do is find a way to make it allocate memory below 4GB.
I don't think you can enforce this restriction for UEFI boot options
with just standard UEFI APIs.

Thanks
Laszlo