From b1e091a6618c070b41468203075f7d35fe512642 Mon Sep 17 00:00:00 2001 From: a1ive <10670106+a1ive@users.noreply.github.com> Date: Sun, 8 Dec 2024 20:01:25 +0900 Subject: [PATCH] add wimboot --- .github/workflows/release.yml | 5 +- .gitignore | 2 + ...FI-LoadFile2-and-InitrdMedia-headers.patch | 180 +++++++++++++++ ..._Fix-optinal-header-in-wimboot-2.8.0.patch | 22 ++ ...mon-vdisk_read_mem_file-cpio-handler.patch | 103 +++++++++ ...pport-EFI-linux-initrd-media-loading.patch | 216 ++++++++++++++++++ wimboot/build.sh | 15 ++ 7 files changed, 542 insertions(+), 1 deletion(-) create mode 100644 wimboot/0001_Add-EFI-LoadFile2-and-InitrdMedia-headers.patch create mode 100644 wimboot/0002_Fix-optinal-header-in-wimboot-2.8.0.patch create mode 100644 wimboot/0003_Provide-common-vdisk_read_mem_file-cpio-handler.patch create mode 100644 wimboot/0004_Support-EFI-linux-initrd-media-loading.patch create mode 100755 wimboot/build.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6163b40..a8a96a9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,12 +14,15 @@ jobs: - name: 初始化 run: | sudo apt update - sudo apt -y install gcc gcc-multilib nasm p7zip-full autoconf automake make patch binutils-dev liblzma-dev gcc-mingw-w64-i686 + sudo apt -y install gcc gcc-multilib nasm p7zip-full autoconf automake make patch binutils-dev liblzma-dev gcc-mingw-w64-i686 libiberty-dev pesign gcab - name: 编译 run: | make -C umbr make -j -C g4dext make -j -C g4eext + cd wimboot && ./build.sh && cd .. + zip -j g4dext-*.zip wimboot/wimboot + zip -j g4eext-*.zip wimboot/wimboot # make -C grubutils/fbinst OSTYPE=MINGW CC=i686-w64-mingw32-gcc # make -C grubutils/loadbin # make -C grubutils/makemod OSTYPE=MINGW CC=i686-w64-mingw32-gcc diff --git a/.gitignore b/.gitignore index 586aa84..8a5f656 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ g4dext/zip grubutils/wee/stage2_size.h grubutils/wee/wee127/stage2_size.h g4eext/bin +wimboot/build +wimboot/wimboot diff --git a/wimboot/0001_Add-EFI-LoadFile2-and-InitrdMedia-headers.patch b/wimboot/0001_Add-EFI-LoadFile2-and-InitrdMedia-headers.patch new file mode 100644 index 0000000..f69da91 --- /dev/null +++ b/wimboot/0001_Add-EFI-LoadFile2-and-InitrdMedia-headers.patch @@ -0,0 +1,180 @@ +From 0e9a72074727a11ee756c8c357fbb2953fca89de Mon Sep 17 00:00:00 2001 +From: a1ive +Date: Sat, 4 Nov 2023 10:32:17 +0800 +Subject: [PATCH] Add EFI LoadFile2 and InitrdMedia headers + +Signed-off-by: a1ive +--- + src/efi.h | 1 + + src/efi/Guid/LinuxEfiInitrdMedia.h | 30 ++++++++++++ + src/efi/Protocol/LoadFile2.h | 78 ++++++++++++++++++++++++++++++ + src/efifile.c | 2 + + src/efiguid.c | 5 ++ + 5 files changed, 116 insertions(+) + create mode 100644 src/efi/Guid/LinuxEfiInitrdMedia.h + create mode 100644 src/efi/Protocol/LoadFile2.h + +diff --git a/src/efi.h b/src/efi.h +index afc7c42..239d64d 100644 +--- a/src/efi.h ++++ b/src/efi.h +@@ -48,5 +48,6 @@ extern EFI_GUID efi_device_path_protocol_guid; + extern EFI_GUID efi_graphics_output_protocol_guid; + extern EFI_GUID efi_loaded_image_protocol_guid; + extern EFI_GUID efi_simple_file_system_protocol_guid; ++extern EFI_GUID efi_load_file2_protocol_guid; + + #endif /* _EFI_H */ +diff --git a/src/efi/Guid/LinuxEfiInitrdMedia.h b/src/efi/Guid/LinuxEfiInitrdMedia.h +new file mode 100644 +index 0000000..5f62027 +--- /dev/null ++++ b/src/efi/Guid/LinuxEfiInitrdMedia.h +@@ -0,0 +1,30 @@ ++/** @file ++ GUID definition for the Linux Initrd media device path ++ ++ Linux distro boot generally relies on an initial ramdisk (initrd) which is ++ provided by the loader, and which contains additional kernel modules (for ++ storage and network, for instance), and the initial user space startup code, ++ i.e., the code which brings up the user space side of the entire OS. ++ ++ In order to provide a standard method to locate this initrd, the GUID defined ++ in this file is used to describe the device path for a LoadFile2 Protocol ++ instance that is responsible for loading the initrd file. ++ ++ The kernel EFI Stub will locate and use this instance to load the initrd, ++ therefore the firmware/loader should install an instance of this to load the ++ relevant initrd. ++ ++ Copyright (c) 2020, Arm, Ltd. All rights reserved.
++ ++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++ ++#ifndef LINUX_EFI_INITRD_MEDIA_GUID_H_ ++#define LINUX_EFI_INITRD_MEDIA_GUID_H_ ++ ++#define LINUX_EFI_INITRD_MEDIA_GUID \ ++ {0x5568e427, 0x68fc, 0x4f3d, {0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68}} ++ ++extern EFI_GUID gLinuxEfiInitrdMediaGuid; ++ ++#endif +diff --git a/src/efi/Protocol/LoadFile2.h b/src/efi/Protocol/LoadFile2.h +new file mode 100644 +index 0000000..2d3a5fd +--- /dev/null ++++ b/src/efi/Protocol/LoadFile2.h +@@ -0,0 +1,78 @@ ++/** @file ++ Load File protocol as defined in the UEFI 2.0 specification. ++ ++ Load file protocol exists to supports the addition of new boot devices, ++ and to support booting from devices that do not map well to file system. ++ Network boot is done via a LoadFile protocol. ++ ++ UEFI 2.0 can boot from any device that produces a LoadFile protocol. ++ ++ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
++ SPDX-License-Identifier: BSD-2-Clause-Patent ++ ++**/ ++ ++#ifndef __EFI_LOAD_FILE2_PROTOCOL_H__ ++#define __EFI_LOAD_FILE2_PROTOCOL_H__ ++ ++#define EFI_LOAD_FILE2_PROTOCOL_GUID \ ++ { \ ++ 0x4006c0c1, 0xfcb3, 0x403e, {0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d } \ ++ } ++ ++/// ++/// Protocol Guid defined by UEFI2.1. ++/// ++#define LOAD_FILE2_PROTOCOL EFI_LOAD_FILE2_PROTOCOL_GUID ++ ++typedef struct _EFI_LOAD_FILE2_PROTOCOL EFI_LOAD_FILE2_PROTOCOL; ++ ++/** ++ Causes the driver to load a specified file. ++ ++ @param This Protocol instance pointer. ++ @param FilePath The device specific path of the file to load. ++ @param BootPolicy Should always be FALSE. ++ @param BufferSize On input the size of Buffer in bytes. On output with a return ++ code of EFI_SUCCESS, the amount of data transferred to ++ Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL, ++ the size of Buffer required to retrieve the requested file. ++ @param Buffer The memory buffer to transfer the file to. IF Buffer is NULL, ++ then no the size of the requested file is returned in ++ BufferSize. ++ ++ @retval EFI_SUCCESS The file was loaded. ++ @retval EFI_UNSUPPORTED BootPolicy is TRUE. ++ @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or ++ BufferSize is NULL. ++ @retval EFI_NO_MEDIA No medium was present to load the file. ++ @retval EFI_DEVICE_ERROR The file was not loaded due to a device error. ++ @retval EFI_NO_RESPONSE The remote system did not respond. ++ @retval EFI_NOT_FOUND The file was not found ++ @retval EFI_ABORTED The file load process was manually canceled. ++ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current ++ directory entry. BufferSize has been updated with ++ the size needed to complete the request. ++ ++ ++**/ ++typedef ++EFI_STATUS ++(EFIAPI *EFI_LOAD_FILE2)( ++ IN EFI_LOAD_FILE2_PROTOCOL *This, ++ IN EFI_DEVICE_PATH_PROTOCOL *FilePath, ++ IN BOOLEAN BootPolicy, ++ IN OUT UINTN *BufferSize, ++ IN VOID *Buffer OPTIONAL ++ ); ++ ++/// ++/// The EFI_LOAD_FILE_PROTOCOL is a simple protocol used to obtain files from arbitrary devices. ++/// ++struct _EFI_LOAD_FILE2_PROTOCOL { ++ EFI_LOAD_FILE2 LoadFile; ++}; ++ ++extern EFI_GUID gEfiLoadFile2ProtocolGuid; ++ ++#endif +diff --git a/src/efifile.c b/src/efifile.c +index 4ce2cd3..f5369d5 100644 +--- a/src/efifile.c ++++ b/src/efifile.c +@@ -35,6 +35,8 @@ + #include "wimfile.h" + #include "efi.h" + #include "efifile.h" ++#include "efi/Protocol/LoadFile2.h" ++#include "efi/Guid/LinuxEfiInitrdMedia.h" + + /** bootmgfw.efi path within WIM */ + static const wchar_t bootmgfw_path[] = L"\\Windows\\Boot\\EFI\\bootmgfw.efi"; +diff --git a/src/efiguid.c b/src/efiguid.c +index 00313fa..6dc3755 100644 +--- a/src/efiguid.c ++++ b/src/efiguid.c +@@ -31,6 +31,7 @@ + #include "efi/Protocol/GraphicsOutput.h" + #include "efi/Protocol/LoadedImage.h" + #include "efi/Protocol/SimpleFileSystem.h" ++#include "efi/Protocol/LoadFile2.h" + + /** Block I/O protocol GUID */ + EFI_GUID efi_block_io_protocol_guid +@@ -51,3 +52,7 @@ EFI_GUID efi_loaded_image_protocol_guid + /** Simple file system protocol GUID */ + EFI_GUID efi_simple_file_system_protocol_guid + = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; ++ ++/** Load File 2 protocol GUID */ ++EFI_GUID efi_load_file2_protocol_guid ++ = EFI_LOAD_FILE2_PROTOCOL_GUID; diff --git a/wimboot/0002_Fix-optinal-header-in-wimboot-2.8.0.patch b/wimboot/0002_Fix-optinal-header-in-wimboot-2.8.0.patch new file mode 100644 index 0000000..9c43c9e --- /dev/null +++ b/wimboot/0002_Fix-optinal-header-in-wimboot-2.8.0.patch @@ -0,0 +1,22 @@ +From 0890cc86c970659dcbefdf5c09c80d975f7184e2 Mon Sep 17 00:00:00 2001 +From: MexIT +Date: Tue, 29 Oct 2024 01:24:47 +0000 +Subject: [PATCH] Fix optinal header in wimboot 2.8.0 + +Thanks @Melanie.Malachite (#1) +--- + src/elf2efi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/elf2efi.c b/src/elf2efi.c +index 3109486..39c8d66 100644 +--- a/src/elf2efi.c ++++ b/src/elf2efi.c +@@ -249,6 +249,7 @@ static struct pe_header efi_pe_header = { + .MinorLinkerVersion = 42, + .SectionAlignment = EFI_IMAGE_ALIGN, + .FileAlignment = EFI_FILE_ALIGN, ++ .MajorImageVersion = 1, + .SizeOfImage = EFI_IMAGE_ALIGN, + .SizeOfHeaders = + ( sizeof ( efi_pe_header ) - diff --git a/wimboot/0003_Provide-common-vdisk_read_mem_file-cpio-handler.patch b/wimboot/0003_Provide-common-vdisk_read_mem_file-cpio-handler.patch new file mode 100644 index 0000000..5ab0753 --- /dev/null +++ b/wimboot/0003_Provide-common-vdisk_read_mem_file-cpio-handler.patch @@ -0,0 +1,103 @@ +From 395f15bb10d35e9f48381898ea3807032e5f8585 Mon Sep 17 00:00:00 2001 +From: a1ive +Date: Sat, 4 Nov 2023 10:51:24 +0800 +Subject: [PATCH] Provide common vdisk_read_mem_file cpio handler + +https://lists.ipxe.org/pipermail/ipxe-devel/2018-November/006339.html + +Signed-off-by: a1ive +--- + src/main.c | 20 +++----------------- + src/vdisk.c | 13 +++++++++++++ + src/vdisk.h | 2 ++ + 3 files changed, 18 insertions(+), 17 deletions(-) + +diff --git a/src/main.c b/src/main.c +index 371c822..7274344 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -226,20 +226,6 @@ static int is_empty_pgh ( const void *pgh ) { + return ( ( dwords[0] | dwords[1] | dwords[2] | dwords[3] ) == 0 ); + } + +-/** +- * Read from file +- * +- * @v file Virtual file +- * @v data Data buffer +- * @v offset Offset +- * @v len Length +- */ +-static void read_file ( struct vdisk_file *file, void *data, size_t offset, +- size_t len ) { +- +- memcpy ( data, ( file->opaque + offset ), len ); +-} +- + /** + * Add embedded bootmgr.exe extracted from bootmgr + * +@@ -337,7 +323,7 @@ static struct vdisk_file * add_bootmgr ( const void *data, size_t len ) { + + /* Add decompressed image */ + return vdisk_add_file ( "bootmgr.exe", initrd, +- decompressed_len, read_file ); ++ decompressed_len, vdisk_read_mem_file ); + } + + DBG ( "...no embedded bootmgr.exe found\n" ); +@@ -356,7 +342,7 @@ static int add_file ( const char *name, void *data, size_t len ) { + struct vdisk_file *file; + + /* Store file */ +- file = vdisk_add_file ( name, data, len, read_file ); ++ file = vdisk_add_file ( name, data, len, vdisk_read_mem_file ); + + /* Check for special-case files */ + if ( strcasecmp ( name, "bootmgr.exe" ) == 0 ) { +@@ -467,7 +453,7 @@ int main ( void ) { + /* Read bootmgr.exe into memory */ + if ( ! bootmgr ) + die ( "FATAL: no bootmgr.exe\n" ); +- if ( bootmgr->read == read_file ) { ++ if ( bootmgr->read == vdisk_read_mem_file ) { + raw_pe = bootmgr->opaque; + } else { + padded_len = ( ( bootmgr->len + PAGE_SIZE - 1 ) & +diff --git a/src/vdisk.c b/src/vdisk.c +index 7885a5b..6685b14 100644 +--- a/src/vdisk.c ++++ b/src/vdisk.c +@@ -613,6 +613,19 @@ void vdisk_read ( uint64_t lba, unsigned int count, void *data ) { + DBG2 ( "\n" ); + } + ++/** ++ * Read virtual file from memory ++ * ++ * @v file Virtual file ++ * @v data Data buffer ++ * @v offset Offset ++ * @v len Length ++ */ ++void vdisk_read_mem_file ( struct vdisk_file *file, void *data, ++ size_t offset, size_t len ) { ++ memcpy ( data, ( file->opaque + offset ), len ); ++} ++ + /** + * Add file to virtual disk + * +diff --git a/src/vdisk.h b/src/vdisk.h +index 7cae51c..b3b526b 100644 +--- a/src/vdisk.h ++++ b/src/vdisk.h +@@ -611,6 +611,8 @@ struct vdisk_file { + extern struct vdisk_file vdisk_files[VDISK_MAX_FILES]; + + extern void vdisk_read ( uint64_t lba, unsigned int count, void *data ); ++extern void vdisk_read_mem_file ( struct vdisk_file *file, void *data, ++ size_t offset, size_t len ); + extern struct vdisk_file * + vdisk_add_file ( const char *name, void *opaque, size_t len, + void ( * read ) ( struct vdisk_file *file, void *data, diff --git a/wimboot/0004_Support-EFI-linux-initrd-media-loading.patch b/wimboot/0004_Support-EFI-linux-initrd-media-loading.patch new file mode 100644 index 0000000..ddeac20 --- /dev/null +++ b/wimboot/0004_Support-EFI-linux-initrd-media-loading.patch @@ -0,0 +1,216 @@ +From a8215cddfed785425d85c61701d1c247bdf93369 Mon Sep 17 00:00:00 2001 +From: a1ive +Date: Sat, 4 Nov 2023 11:42:09 +0800 +Subject: [PATCH] Support EFI linux initrd media loading + +Signed-off-by: a1ive +--- + src/efifile.c | 146 ++++++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 124 insertions(+), 22 deletions(-) + +diff --git a/src/efifile.c b/src/efifile.c +index f5369d5..aa35a11 100644 +--- a/src/efifile.c ++++ b/src/efifile.c +@@ -31,10 +31,12 @@ + #include "wimboot.h" + #include "vdisk.h" + #include "cmdline.h" ++#include "cpio.h" + #include "wimpatch.h" + #include "wimfile.h" + #include "efi.h" + #include "efifile.h" ++#include "efipath.h" + #include "efi/Protocol/LoadFile2.h" + #include "efi/Guid/LinuxEfiInitrdMedia.h" + +@@ -53,9 +55,29 @@ static const wchar_t *efi_wim_paths[] = { + NULL + }; + ++/** 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), ++}; ++ + /** bootmgfw.efi file */ + struct vdisk_file *bootmgfw; + ++ ++/** WIM image file */ ++static struct vdisk_file *bootwim; ++ ++static void ( * efi_read_func ) ( struct vdisk_file *file, void *data, ++ size_t offset, size_t len ); ++ + /** + * Get architecture-specific boot filename + * +@@ -131,6 +153,97 @@ static void efi_patch_bcd ( struct vdisk_file *vfile __unused, void *data, + } + } + ++/** ++ * File handler ++ * ++ * @v name File name ++ * @v data File data ++ * @v len Length ++ * @ret rc Return status code ++ */ ++static int efi_add_file ( const char *name, void *data, size_t len) { ++ struct vdisk_file *vfile; ++ char bootarch[32]; ++ ++ snprintf ( bootarch, sizeof ( bootarch ), "%ls", efi_bootarch() ); ++ ++ vfile = vdisk_add_file ( name, data, len, efi_read_func ); ++ ++ /* Check for special-case files */ ++ if ( ( strcasecmp ( name, bootarch ) == 0 ) || ++ ( strcasecmp ( name, "bootmgfw.efi" ) == 0 ) ) { ++ DBG ( "...found bootmgfw.efi file %s\n", name ); ++ bootmgfw = vfile; ++ } else if ( strcasecmp ( name, "BCD" ) == 0 ) { ++ DBG ( "...found BCD\n" ); ++ vdisk_patch_file ( vfile, efi_patch_bcd ); ++ } else if ( strcasecmp ( ( name + ( strlen ( name ) - 4 ) ), ++ ".wim" ) == 0 ) { ++ DBG ( "...found WIM file %s\n", name ); ++ bootwim = vfile; ++ } ++ ++ return 0; ++} ++ ++/** ++ * Extract files from Linux initrd media ++ * ++ * @ret rc Return status code ++ */ ++static int ++efi_extract_initrd (void) ++{ ++ EFI_BOOT_SERVICES *bs = efi_systab->BootServices; ++ EFI_HANDLE lf2_handle; ++ EFI_LOAD_FILE2_PROTOCOL *lf2; ++ EFI_DEVICE_PATH_PROTOCOL *dp = ( EFI_DEVICE_PATH_PROTOCOL * ) &efi_initrd_path; ++ UINTN initrd_len = 0; ++ UINTN pages; ++ void *initrd; ++ EFI_PHYSICAL_ADDRESS phys; ++ EFI_STATUS efirc; ++ ++ /* Locate initrd media device */ ++ efirc = bs->LocateDevicePath ( &efi_load_file2_protocol_guid, ++ &dp, &lf2_handle ); ++ if ( efirc != EFI_SUCCESS ) ++ return -1; ++ DBG ( "...found initrd media device\n" ); ++ ++ /* Get LoadFile2 protocol */ ++ efirc = bs->HandleProtocol ( lf2_handle, &efi_load_file2_protocol_guid, ++ ( void ** ) &lf2 ); ++ if ( efirc != EFI_SUCCESS ) ++ die ( "Could not get LoadFile2 protocol.\n" ); ++ ++ /* Get initrd size */ ++ efirc = lf2->LoadFile ( lf2, dp, FALSE, &initrd_len, NULL ); ++ if ( initrd_len == 0 ) ++ die ( "Could not get initrd size\n" ); ++ ++ /* Allocate memory */ ++ pages = ( ( initrd_len + PAGE_SIZE - 1 ) / PAGE_SIZE ); ++ if ( ( efirc = bs->AllocatePages ( AllocateAnyPages, ++ EfiLoaderData, pages, ++ &phys ) ) != 0 ) { ++ die ( "Could not allocate %ld pages: %#lx\n", ++ ( ( unsigned long ) pages ), ( ( unsigned long ) efirc ) ); ++ } ++ initrd = ( ( void * ) ( intptr_t ) phys ); ++ ++ /* Read initrd */ ++ efirc = lf2->LoadFile ( lf2, dp, FALSE, &initrd_len, initrd ); ++ if (efirc != EFI_SUCCESS) ++ die ("Could not read initrd.\n"); ++ ++ efi_read_func = vdisk_read_mem_file; ++ if ( cpio_extract ( initrd, initrd_len, efi_add_file ) != 0 ) ++ die ( "FATAL: could not extract initrd files\n" ); ++ ++ return 0; ++} ++ + /** + * Extract files from EFI file system + * +@@ -147,14 +260,16 @@ void efi_extract ( EFI_HANDLE handle ) { + CHAR16 name[ VDISK_NAME_LEN + 1 /* WNUL */ ]; + } __attribute__ (( packed )) info; + char name[ VDISK_NAME_LEN + 1 /* NUL */ ]; +- struct vdisk_file *wim = NULL; +- struct vdisk_file *vfile; + EFI_FILE_PROTOCOL *root; + EFI_FILE_PROTOCOL *file; + UINTN size; + CHAR16 *wname; + EFI_STATUS efirc; + ++ /* Extract files from initrd media */ ++ if ( efi_extract_initrd () == 0 ) ++ goto proc_wim; ++ + /* Open file system */ + if ( ( efirc = bs->OpenProtocol ( handle, + &efi_simple_file_system_protocol_guid, +@@ -200,34 +315,21 @@ void efi_extract ( EFI_HANDLE handle ) { + + /* Add file */ + snprintf ( name, sizeof ( name ), "%ls", wname ); +- vfile = vdisk_add_file ( name, file, info.file.FileSize, +- efi_read_file ); +- +- /* Check for special-case files */ +- if ( ( wcscasecmp ( wname, efi_bootarch() ) == 0 ) || +- ( wcscasecmp ( wname, L"bootmgfw.efi" ) == 0 ) ) { +- DBG ( "...found bootmgfw.efi file %ls\n", wname ); +- bootmgfw = vfile; +- } else if ( wcscasecmp ( wname, L"BCD" ) == 0 ) { +- DBG ( "...found BCD\n" ); +- vdisk_patch_file ( vfile, efi_patch_bcd ); +- } else if ( wcscasecmp ( ( wname + ( wcslen ( wname ) - 4 ) ), +- L".wim" ) == 0 ) { +- DBG ( "...found WIM file %ls\n", wname ); +- wim = vfile; +- } ++ efi_read_func = efi_read_file; ++ efi_add_file ( name, file, info.file.FileSize ); + } + ++proc_wim: + /* Process WIM image */ +- if ( wim ) { +- vdisk_patch_file ( wim, patch_wim ); ++ if ( bootwim ) { ++ vdisk_patch_file ( bootwim, patch_wim ); + if ( ( ! bootmgfw ) && +- ( bootmgfw = wim_add_file ( wim, cmdline_index, ++ ( bootmgfw = wim_add_file ( bootwim, cmdline_index, + bootmgfw_path, + efi_bootarch() ) ) ) { + DBG ( "...extracted %ls\n", bootmgfw_path ); + } +- wim_add_files ( wim, cmdline_index, efi_wim_paths ); ++ wim_add_files ( bootwim, cmdline_index, efi_wim_paths ); + } + + /* Check that we have a boot file */ diff --git a/wimboot/build.sh b/wimboot/build.sh new file mode 100755 index 0000000..61f4ad3 --- /dev/null +++ b/wimboot/build.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +rm -rf build + +git clone https://github.com/ipxe/wimboot.git build && cd build +git checkout v2.8.0 + +git apply ../0001_Add-EFI-LoadFile2-and-InitrdMedia-headers.patch +git apply ../0002_Fix-optinal-header-in-wimboot-2.8.0.patch +git apply ../0003_Provide-common-vdisk_read_mem_file-cpio-handler.patch +git apply ../0004_Support-EFI-linux-initrd-media-loading.patch + +make -C src wimboot.x86_64 + +mv src/wimboot.x86_64 ../wimboot