5

I know there have been quite a few similar questions, but they aren't specific enough.

I have a Windows 10 x64 installation ISO and I am trying to extract the files make some modifications and then make a new ISO from the extracted/modified files.

It basically works just fine, but the problem is that I can't figure out how to make it UEFI bootable again (in legacy/BIOS mode it boots just fine).

I have gone through countless posts following instructions on how to do this, but none of them worked for my Windows 10 ISO. Most of these posts only mention older versions of Windows and those mentioning Windows 10 don't specify if they got it to work with a current x64 version and if they were able to UEFI boot from it. (Probably not, because is surely doesn't work for me.)

I ended up trying to replicate the output of isoinfo -d -i ./windows10.iso and dumpet -i ./windows10.iso as much as I could.

And this is as close as I was able to get: (Edit: Updated with -eltorito-alt-boot as suggestes by telcoM)

Original ISO (isoinfo):

$ isoinfo -d -i ./original.iso
CD-ROM is in ISO 9660 format
System id: 
Volume id: CCCOMA_X64FRE_EN-US_DV9
Volume set id: CCCOMA_X64FRE_EN-US_DV9
Publisher id: MICROSOFT CORPORATION
Data preparer id: MICROSOFT CORPORATION, ONE MICROSOFT WAY, REDMOND WA 98052, (425) 882-8080
Application id: CDIMAGE 2.56 (01/01/2005 TM)
Copyright File id: 
Abstract File id: 
Bibliographic File id: 
Volume set size is: 1
Volume set sequence number is: 1
Logical block size is: 2048
Volume size is: 2411879
El Torito VD version 1 found, boot catalog is in sector 22
NO Joliet present
NO Rock Ridge present
Eltorito validation header:
    Hid 1
    Arch 0 (x86)
    ID 'Microsoft Corporation'
    Key 55 AA
    Eltorito defaultboot header:
        Bootid 88 (bootable)
        Boot media 0 (No Emulation Boot)
        Load segment 0
        Sys type 0
        Nsect 8
        Bootoff 202 514

Modified ISO (isoinfo):

$ isoinfo -d -i ./modified.iso
CD-ROM is in ISO 9660 format
System id: 
Volume id: CCCOMA_X64FRE_EN-US_DV9
Volume set id: CCCOMA_X64FRE_EN-US_DV9
Publisher id: Microsoft Corporation
Data preparer id: MICROSOFT CORPORATION, ONE MICROSOFT WAY, REDMOND WA 98052, (425) 882-8080
Application id: CDIMAGE 2.56 (01/01/2005 TM)
Copyright File id: 
Abstract File id: 
Bibliographic File id: 
Volume set size is: 1
Volume set sequence number is: 1
Logical block size is: 2048
Volume size is: 2411275
El Torito VD version 1 found, boot catalog is in sector 1506
NO Joliet present
NO Rock Ridge present
Eltorito validation header:
    Hid 1
    Arch 0 (x86)
    ID 'Microsoft Corporation'
    Key 55 AA
    Eltorito defaultboot header:
        Bootid 88 (bootable)
        Boot media 0 (No Emulation Boot)
        Load segment 0
        Sys type 0
        Nsect 8
        Bootoff 8CD 2253

Difference between the above isoinfo outputs:

$ diff <(isoinfo -i ./original.iso) <(isoinfo -i ./modified.iso)
5c5
< Publisher id: MICROSOFT CORPORATION
---
> Publisher id: Microsoft Corporation
14,15c14,15
< Volume size is: 2411879
< El Torito VD version 1 found, boot catalog is in sector 22
---
> Volume size is: 2411275
> El Torito VD version 1 found, boot catalog is in sector 1506
29c29
<         Bootoff 202 514
---
>         Bootoff 8CD 2253

Original ISO (dumpet):

$ dumpet -i ./original.iso
Validation Entry:
        Header Indicator: 0x01 (Validation Entry)
        PlatformId: 0x00 (80x86)
        ID: "Microsoft Corporation"
        Checksum: 0x494c
        Key bytes: 0x55aa
Boot Catalog Default Entry:
        Entry is bootable
        Boot Media emulation type: no emulation
        Media load segment: 0x0 (0000:7c00)
        System type: 0 (0x00)
        Load Sectors: 8 (0x0008)
        Load LBA: 514 (0x00000202)
Section Header Entry:
        Header Indicator: 0x91 (Final Section Header Entry)
        PlatformId: 0xef (EFI)
        Section Entries: 1
        ID: ""
Boot Catalog Section Entry:
        Entry is bootable
        Boot Media emulation type: no emulation
        Media load address: 0 (0x0000)
        System type: 0 (0x00)
        Load Sectors: 1 (0x0001)
        Load LBA: 516 (0x00000204)

Modified ISO (dumpet):

$ dumpet -i ./modified.iso 
Validation Entry:
        Header Indicator: 0x01 (Validation Entry)
        PlatformId: 0x00 (80x86)
        ID: "Microsoft Corporation"
        Checksum: 0x494c
        Key bytes: 0x55aa
Boot Catalog Default Entry:
        Entry is bootable
        Boot Media emulation type: no emulation
        Media load segment: 0x0 (0000:7c00)
        System type: 0 (0x00)
        Load Sectors: 8 (0x0008)
        Load LBA: 2253 (0x000008cd)
Section Header Entry:
        Header Indicator: 0x91 (Final Section Header Entry)
        PlatformId: 0xef (EFI)
        Section Entries: 1
        ID: ""
Boot Catalog Section Entry:
        Entry is bootable
        Boot Media emulation type: no emulation
        Media load address: 0 (0x0000)
        System type: 0 (0x00)
        Load Sectors: 2984 (0x0ba8)
        Load LBA: 1507 (0x000005e3)

Difference between the above dumpet outputs:

$ diff <(dumpet -i ./original.iso) <(dumpet -i ./modified.iso)
13c13
<       Load LBA: 514 (0x00000202)
---
>       Load LBA: 2253 (0x000008cd)
24,25c24,25
<       Load Sectors: 1 (0x0001)
<       Load LBA: 516 (0x00000204)
---
>       Load Sectors: 2984 (0x0ba8)
>       Load LBA: 1507 (0x000005e3)

I have written a script to completely reproduce the problem with the same ISO that I'm using:

#!/usr/bin/env bash

##################################
# Download the Windows 10 x64 ISO

WIN10_IMG_DESTINATION="./windows.iso"
WIN10_IMG_ARCH="x64"

if [ ! -f "${WIN10_IMG_DESTINATION}" ]; then
    if [[ "$WIN10_IMG_ARCH" == "x86" ]] || [[ "$WIN10_IMG_ARCH" == "i386" ]] ; then
        echo "Retrieving the x86 Windows 10 iso URL..."
        WINDOWS_10_ISO_URL=$(curl -LsI -o /dev/null -w %{url_effective} "https://windows101tricks.com/1903-iso-32")
    else
        echo "Retrieving the x64 Windows 10 iso URL..."
        WINDOWS_10_ISO_URL=$(curl -LsI -o /dev/null -w %{url_effective} "https://windows101tricks.com/1903-iso-64")
    fi

    echo "Making sure the URL comes from a trusted Microsoft (sub)domain..."
    if [[ $WINDOWS_10_ISO_URL == https://software-download.microsoft.com/* ]] ; then
        echo "Downloading the Windows 10 installation iso..."
        wget "$WINDOWS_10_ISO_URL" -O "$WIN10_IMG_DESTINATION"
    else
        echo "URL validation failed. Please download the Windows 10 iso manually."
        exit 1
    fi
else
    echo "Windows 10 iso already exists. Skipping download..."
fi
#
##################################



# Variable containing the path to the windows.iso
WIN10_IMG="$WIN10_IMG_DESTINATION"

TMP="./tmp"
ISO_FILES="${TMP}/iso-files"
ISO_MP="${TMP}/iso-mountpoint"

# Remove ./tmp if it already exists, then create ./tmp/iso-files and ./tmp/iso-mountpoint
rm -rf "${TMP}"
mkdir -p "${ISO_FILES}"
mkdir -p "${ISO_MP}"
# Extract the files fromt he ISO to ./tmp/iso-files
sudo mount -t udf "${WIN10_IMG}" "${ISO_MP}"
sudo cp -Rva ${ISO_MP}/* "${ISO_FILES}"
sudo umount "${ISO_MP}"

# Make modifications to the Windows ISO
#BOOT_DIR="${ISO_FILES}/efi/microsoft/boot"
#sudo mv "${BOOT_DIR}/cdboot.efi" "${BOOT_DIR}/tmp.efi"
#sudo mv "${BOOT_DIR}/cdboot_noprompt.efi" "${BOOT_DIR}/cdboot.efi"
#sudo mv "${BOOT_DIR}/tmp.efi" "${BOOT_DIR}/cdboot_noprompt.efi"

# Extract the boot.img (didn't help at all)
#BOOT_SECTOR_LENGTH="$(isoinfo -d -i "${WIN10_IMG}" | grep "Nsect " | grep -o "[^ ]*$")"
#STARTING_SECTOR="$(isoinfo -d -i ./vm-files/windows10.iso | grep "Bootoff " | grep -o "[^ ]*$")"
#dd if="${WIN10_IMG}" of="${ISO_FILES}/boot.img" bs=2048 count="${BOOT_SECTOR_LENGTH}" skip="${STARTING_SECTOR}"


# Extract boot load segment address and size
BOOT_LOAD_SEG="$(dumpet -i "${WIN10_IMG}" | grep "Media load segment: " | cut -d ':' -f2 | cut -d ' ' -f2)"
BOOT_LOAD_SIZE="$(dumpet -i "${WIN10_IMG}" | grep "Load Sectors: " | grep -o "[^:]*$" | cut -d ' ' -f2 | head -1)"

# Extract meta data :
SYSTEM_ID="$(isoinfo -d -i "${WIN10_IMG}" | grep "System id: " | cut -d ' ' -f3-)"
VOLUME_ID="$(isoinfo -d -i "${WIN10_IMG}" | grep "Volume id: " | cut -d ' ' -f3-)"
VOLUME_SET_ID="$(isoinfo -d -i "${WIN10_IMG}" | grep "Volume set id: " | cut -d ' ' -f4-)"
#PUBLISHER_ID="$(isoinfo -d -i "${WIN10_IMG}" | grep "Publisher id: " | cut -d ' ' -f3-)" # Always uppercase
PUBLISHER_ID="$(isoinfo -d -i "${WIN10_IMG}" | grep "ID '" | cut -d "'" -f2)"
DATA_PREPARER_ID="$(isoinfo -d -i "${WIN10_IMG}" | grep "Data preparer id: " | cut -d ' ' -f4-)"
APPLICATION_ID="$(isoinfo -d -i "${WIN10_IMG}" | grep "Application id: " | cut -d ' ' -f3-)"
COPYRIGHT_FILE_ID="$(isoinfo -d -i "${WIN10_IMG}" | grep "Copyright file id: " | cut -d ' ' -f4-)"
ABSTRACT_FILE_ID="$(isoinfo -d -i "${WIN10_IMG}" | grep "Abstract file id: " | cut -d ' ' -f4-)"
BIBLIOGRAPHIC_FILE_ID="$(isoinfo -d -i "${WIN10_IMG}" | grep "Bibliographic file id: " | cut -d ' ' -f4-)"

# Create a new ISO image using mkisofs
# (.mkisofsrc is necessary, because some options are not available on the cli directly)
rm ".mkisofsrc"
echo "APPI=${APPLICATION_ID}" >> ".mkisofsrc"
echo "COPY=${COPYRIGHT_FILE_ID}" >> ".mkisofsrc"
echo "ABST=${ABSTRACT_FILE_ID}" >> ".mkisofsrc"
echo "BIBL=${BIBLIOGRAPHIC_FILE_ID}" >> ".mkisofsrc"
echo "PREP=${DATA_PREPARER_ID}" >> ".mkisofsrc"
echo "PUBL=${PUBLISHER_ID}" >> ".mkisofsrc"
echo "SYSI=${SYSTEM_ID}" >> ".mkisofsrc"
echo "VOLI=${VOLUME_ID}" >> ".mkisofsrc"
echo "VOLS=${VOLUME_SET_ID}" >> ".mkisofsrc"

sudo rm "${WIN10_IMG}.tmp.iso"
sudo mkisofs \
  -no-emul-boot \
  -b boot/etfsboot.com \
  -boot-load-seg "${BOOT_LOAD_SEG}" \
  -boot-load-size "${BOOT_LOAD_SIZE}" \
  -eltorito-alt-boot \
  -e efi/boot/bootx64.efi \
  -no-emul-boot \
  -iso-level 2 \
  -boot-info-table \
  -udf \
  -D \
  -N \
  -relaxed-filenames \
  -allow-lowercase \
  -o "${WIN10_IMG}.tmp.iso" \
  "${ISO_FILES}"

rm ".mkisofsrc"


# Print the variables that we gathered
echo
echo "Extracted meta data (form original image):"
echo "BOOT_LOAD_SEG: ${BOOT_LOAD_SEG}"
echo "BOOT_LOAD_SIZE: ${BOOT_LOAD_SIZE}"
echo "-------"
echo "SYSTEM_ID: ${SYSTEM_ID}"
echo "VOLUME_ID: ${VOLUME_ID}"
echo "VOLUME_SET_ID: ${VOLUME_SET_ID}"
echo "PUBLISHER_ID: ${PUBLISHER_ID}"
echo "DATA_PREPARER_ID: ${DATA_PREPARER_ID}"
echo "APPLICATION_ID: ${APPLICATION_ID}"
echo "COPYRIGHT_FILE_ID: ${COPYRIGHT_FILE_ID}"
echo "ABSTRACT_FILE_ID: ${ABSTRACT_FILE_ID}"
echo "BIBLIOGRAPHIC_FILE_ID: ${BIBLIOGRAPHIC_FILE_ID}"

# Show difference between new and old image as reported by isoinfo
echo
echo "-------------- isoinfo diff -----------------"
diff <(isoinfo -d -i "${WIN10_IMG}") <(isoinfo -d -i "${WIN10_IMG}.tmp.iso")

# Show difference between new and old image as reported by dumpet
echo
echo " -------------- dumpet diff -----------------"
diff <(dumpet -i "${WIN10_IMG}") <(dumpet -i "${WIN10_IMG}.tmp.iso")


# Overwrite the original ISO with the new one
#sudo rm "${WIN10_IMG}"
#sudo mv "${WIN10_IMG}.tmp.iso" "${WIN10_IMG}"
1
  • You may get better answers, if you change the title, so that it does not appear to be about MS-Windows (without having to read the whole question). Jul 22, 2019 at 13:19

5 Answers 5

5
+50

The dumpet output indicates the original contains two ElTorito boot images: one for BIOS-style boot and another for UEFI. After specifying the first boot image for BIOS with mkisofs options, you would need to use the -eltorito-alt-boot and -eltorito-platform efi options to specify a second boot image. Something like this:

sudo mkisofs \
  -no-emul-boot \
  -b boot/etfsboot.com \
  -boot-load-seg "${BOOT_LOAD_SEG}" \
  -boot-load-size "${BOOT_LOAD_SIZE}" \
  -eltorito-alt-boot \
  -b <UEFI boot image name here> \
  -eltorito-platform efi \
  [...]

I don't know for sure what file might be used as the UEFI boot image.


Update: I got my hands on an original Windows 10 ISO image, and did a bit of experimentation. On my version, the Load LBA value was 519 for the UEFI boot entry. Remembering that a CD-ROM block size is 2048 bytes, I dumped the block:

$ dd if=<silly_long_name>.iso bs=2048 skip=519 count=1 > win_efi_boot.dmp

$ file win_efi_boot.dmp
win_efi_boot.dmp: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "MSDOS5.0", 
root entries 224, sectors 2880 (volumes <=32 MB) , sectors/FAT 9, sectors/track 18, 
serial number 0xef56c0, label: "EFISECTOR  ", FAT (12 bit), followed by FAT

Looks like the beginning of a 1.4 MB floppy image. 2880 floppy sectors * 512 bytes per floppy sector / 2048 bytes per CD-ROM sector = 720 CD-ROM sectors. I guess the firmware just ignores the Load Sectors value, and looks at the FAT boot sector to find the real size.

dd if=<silly_long_name>.iso bs=2048 skip=519 count=720 of=win_efi_boot.img

And yes, it contains a (v)FAT12 filesystem with just one file: \EFI\BOOT\BOOTX64.EFI, sized 936352 bytes.

$ sudo mount -o loop,ro win_efi_boot.img /mnt
$ ls -l /mnt/EFI/BOOT/BOOTX64.EFI
-rwxr-xr-x 1 root root 936352 Apr 11  2018 /mnt/EFI/BOOT/BOOTX64.EFI

I also hex-dumped the win_efi_boot.img file: after the end of the BOOTX64.EFI file, the rest of the floppy image is filled with all zero bytes, so I think the count=720 is accurate.

So, you should be able to do the same to rip the UEFI boot filesystem image from the original ISO (like my win_efi_boot.img), and use that with your -e option.

6
  • I think the UEFI boot image is efi/boot/bootx64.efi. -eltorito-platform doesn't exist, but I can use -e instead of -b to specify the efi image. Using -eltorito-alt-boot -e efi/boot/bootx64.efi -no-emul-boot the output of dumpet becomes almost identical, the only difference being in Load Sectors and Load LBA. I have tried adding -boot-load-size 1` to also make the Load Sectors equal, but it still didn't boot. I have tried booting it in BIOS mode just to see what happens and that works, but as I said in UEFI mode it doesn't.
    – Forivin
    Jul 24, 2019 at 9:42
  • The different options indicate you are apparently using a version of the ISO filesystem creation tool that is different from mine, but that's not a problem. I got my hands on a genuine Windows ISO image and did some digging: see my edit above for a procedure you might try.
    – telcoM
    Jul 24, 2019 at 13:06
  • 1
    Thanks for all your effort! I tried using the win_efi_boot.img in the -e option and I also tried using the BOOTX64.EFI extracted from the img directly. But it's still not booting. I noticed my file sizes are different btw: original bootx64.efi from the ISO: 1526072 bytes; dumped img: 5898240 bytes; extracted efi: 1144328 bytes (Using the official Windows 10 x64 version 1903 (May 2019) enUS iso)
    – Forivin
    Jul 24, 2019 at 14:17
  • 1
    Btw, this assumes that the startsector is 1. If startsector 32, for example, that has to be added to the Load LBA values. i.e. skip=519 would become skip=527. ( 32 * 512 / 2048 ) + ( 519) = 527. Then, the rest works as expected.
    – ILMostro_7
    Oct 29, 2019 at 5:04
  • 1
    @Forivin Be careful, if your "mkisofs" supports -e, it is not mkisofs, but a so called fork, that still in the state from May 2004 + a few bad hacks from Debian. It is not recommended to use that outdated version, as it creates filesystems with structural errors. Also note that you may need -boot-load-size for EFI as well.
    – schily
    May 11, 2020 at 9:03
3

To expand on and adumbrate the useful information @telcoM has provided above I provide this procedure which landed me with a working (i.e. EFI bootable, Wn10_20H2_v2_English_x64.iso) ISO. My intent was to split the install.wim file as to allow installation from a FAT32 USB drive and simple ISO usage with Ventoy.

Quick overview:

  • used Schily tools to get around possible mkisofs issues
  • used Wimlib to split the wim archive
  • used telcoM's method to extract the boot floppy image from the ISO. Seems to be crucial to use the actual floppy image. boofx64.efi contained within does not appear to be the same file as the one from the efi/boot/ directory
  • the ISO building process is semi-automated, as the user will be prompted for the floppy image LBA and the final size (which presumably will always be 720 sectors)

The script:

#!/bin/bash

# provide paths, no closing /

ISO_IMAGE="/path/to/Win10.iso"
ISO_IMAGE_OUT="/path/to/Win10_split.iso"
WORKING_DIR="/home/user/working"

echo "Paths set"
echo "ISO_IMAGE $ISO_IMAGE"
echo "WORKING DIRECTORY: $WORKING_DIR"

# prerequisites
# sudo apt-get install libxml2-dev ntfs-3g-dev libfuse-dev libattr1-dev dumpet

# install schily tools http://schilytools.sourceforge.net/
# alias smake=/opt/schily/bin/smake
# alias mkisofs=/opt/schily/bin/mkisofs

# install wimlib https://wimlib.net/

# git clone git://wimlib.net/wimlib
# cd wimlib

# libtoolize --force
# aclocaldc
# autoheader
# automake --force-missing --add-missing
# autoconf
# ./configure

# sudo make install
# gsudo ldconfig -v

printf "\nRemoving/recreating the working directory\n"
rm -r -d -f $WORKING_DIR
mkdir $WORKING_DIR

printf "\nMounting the ISO image\n"
sudo mount -r -t udf $ISO_IMAGE /media/iso

printf "\nCopying the ISO image contents to the working directory\n"
cp -r /media/iso/* $WORKING_DIR
chmod -R 755 $WORKING_DIR

printf "\nUnmounting the ISO image\n"
sudo umount /media/iso

printf "\nSplitting the install.wim archive\n"
wimsplit $WORKING_DIR/sources/install.wim $WORKING_DIR/sources/install.swm 2000
rm -d -f $WORKING_DIR/sources/install.wim

printf "\nGetting the boot image LBA from the ISO\n----------\n"
dumpet -i $ISO_IMAGE

printf "\nShould be a integer number following the second 'Load LBA': "
read LOAD_LBA

printf "\n"
dd if=$ISO_IMAGE bs=2048 skip=$LOAD_LBA count=1 > $WORKING_DIR/efi/win_efi_boot.img

printf "\nNow we get the boot.img and check the right file size.\nThe below output should detect a 'DOS/MBR boot sector' and sectors size should be 2880 which would mean 2880 * 512 / 2048 = 720.\n----------\n"
file $WORKING_DIR/efi/win_efi_boot.img

printf "\nThat would make the input 720: "
read LOAD_COUNT

printf "\n"
dd if=$ISO_IMAGE bs=2048 skip=$LOAD_LBA count=$LOAD_COUNT > $WORKING_DIR/efi/win_efi_boot.img

printf "\nBuilding an image\n"
/opt/schily/bin/mkisofs \
-no-emul-boot \
-b boot/etfsboot.com \
-boot-load-seg 0 \
-boot-load-size 8 \
-eltorito-alt-boot \
-no-emul-boot \
-b efi/win_efi_boot.img \
-boot-load-size 1 \
-iso-level 4 \
-UDF \
-o $ISO_IMAGE_OUT \
$WORKING_DIR/

printf "\n\nImage ready!\n\n" 
4
  • 1
    Thanks for the answer @mkey. What is Schily Tools? Did you install it because your distro doesn't come with mkisofs? Or does Shily Tools provide a modified mkisofs with some sort of patches? And I have another question, did you really mean "-UDF" because that would be equivalent to "-U -D -F" and not "-udf". Sicne -F doesn't exist (at least with my version of mkisofs, it throws an error: invalid option -- 'F'.
    – Forivin
    Feb 26, 2021 at 11:38
  • 1
    btw For wimlib I simply used the one that came with my distro's package manager. Is there a reason why you installed it from source? Anyway when I try to do it the way you did with the same image you used, but with -udf instead of -UDF I still don't end up with an EFI bootable image.
    – Forivin
    Feb 26, 2021 at 11:50
  • @Forivin yes, Schily tools packs an updated mfisofs, among many other tools and I used it specifically because the author claimed genisomage has some ancient bugs in there. UDF is supposed to be used for UDF in the Schily version of mkisofs.
    – mkey
    Mar 13, 2021 at 17:36
  • @Forivin I didn't have wimlib installed so I installed from source to be sure what I'm getting. But in your case, the fact you are not getting an EFI bootable image is not related to wimlib for sure. I'd start from Shily tools because that's what got me going on my end. I doubt genisoimage can produce an EFI bootable image.
    – mkey
    Mar 13, 2021 at 17:38
1

See Here:

Create a Custom ISO for Windows 10: Part 1 of 6

If I had to guess thee ISO won't boot in UEFI because you're doing a direct copy of the boot sector. You can't do that. See Part 5, which uses DISM - Deployment Image Servicing and Management. Microsoft built native tools to do exactly what you want, but they expect you to use a working Windows Environment to accomplish the task. You may also need the Windows ADK - Windows Assessment and Deployment Kit if you follow the Blog sections I linked above.

1

You can try with the following command:

mkisofs -iso-level 4 -l -R -UDF -D -b Boot/etfsboot.com -no-emul-boot -boot-load-size 8 -hide boot.catalog -eltorito-alt-boot -eltorito-platform efi -no-emul-boot -b efi/microsoft/boot/efisys.bin -o modified.iso .\source

Taken from here: http://forum.imgburn.com/index.php?/topic/24193-problem-i-can-not-create-a-uefi-bootable-iso-image/&do=findComment&comment=158044

0

I've spent a long time experimenting with the dd method described above. However, that one only partially dumps to EFI boot code and in turn the EFI-Boot will still fail. I found the important hint at: https://docs.microsoft.com/en-us/troubleshoot/windows-server/deployment/create-iso-image-for-uefi-platforms

The boot code for efi is located at "efi/microsoft/boot/efisys.bin"

Knowing that detail the rest is straight forward. It just varies a bit depending on the variant of mkisofs on a specific *nix system. I've successfully tested the following two examples, even UEFI Secure Boot works.

Cent-OS:

genisoimage \
  --allow-limited-size \
  -no-emul-boot \
  -b "boot/etfsboot.com" \
  -boot-load-seg 0 \
  -boot-load-size 8 \
  -eltorito-alt-boot \
  -no-emul-boot \
  -e "efi/microsoft/boot/efisys.bin" \
  -boot-load-size 1 \
  -iso-level 4 \
  -udf \
  -o "win.iso" \
  "source/"

MacOS (mac brew):

mkisofs \
  -no-emul-boot \
  -b "boot/etfsboot.com" \
  -boot-load-seg 0 \
  -boot-load-size 8 \
  -eltorito-alt-boot \
  -eltorito-platform efi \
  -no-emul-boot \
  -b "efi/microsoft/boot/efisys.bin" \
  -boot-load-size 1 \
  -iso-level 4 \
  -UDF \
  -o "win.iso" \
  "source/"
1
  • The answer ain't bad, but @nubjai has suggested basically the same thing. Might be a better idea to just edit their answer to add the efisys explanation and the genisoimage command. Sep 5, 2021 at 11:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.