ipxe / wimboot

WIM bootloader
https://ipxe.org/wimboot
GNU General Public License v2.0
238 stars 42 forks source link

Added support for loading initrd via the EFI LoadFile2 protocol #49

Closed a1ive closed 7 months ago

a1ive commented 1 year ago

GRUB 2.12-rc1 has added support for loading initrd using the LoadFile2 protocol on x86 platforms. http://git.savannah.gnu.org/cgit/grub.git/commit/?id=cfbfae1aef0694b416aa199291cfef7596cdfc20 With this change, wimboot can be loaded by GRUB (2.12-rc1+) under EFI.

menuentry "Wimboot" {
    linux /wimboot
    initrd newc:boot.wim:/src/boot.wim \
           newc:bcd:/src/bcd \
           newc:boot.sdi:/src/boot.sdi \
           newc:bootx64.efi:/src/bootx64.efi
}

http://git.savannah.gnu.org/cgit/grub.git/tree/grub-core/loader/efi/linux.c

/*
   * Linux kernels built for any architecture are guaranteed to support the
   * LoadFile2 based initrd loading protocol if the image version is >= 1.
   */
  if (lh->pe_image_header.optional_header.major_image_version >= 1)
    initrd_use_loadfile2 = true;
  else
    initrd_use_loadfile2 = false;

If GRUB detects that MajorImageVersion in the opt header is greater than or equal to 1, it will load initrd using the LoadFile2 protocol.

The device path of initrd is hard-coded, and the GUID is LINUX_EFI_INITRD_MEDIA_GUID.

/** Linux initrd media device path */
static struct {
    VENDOR_DEVICE_PATH vendor;
    EFI_DEVICE_PATH_PROTOCOL end;
} __attribute__ ((packed)) efi_initrd_path = {
    .vendor = {
        .Header = EFI_DEVPATH_INIT (efi_initrd_path.vendor,
                                    MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP),
        .Guid = LINUX_EFI_INITRD_MEDIA_GUID,
    },
    .end = EFI_DEVPATH_END_INIT (efi_initrd_path.end),
};

wimboot can read the cpio initrd using LoadFile2->LoadFile.