For*_*vin 5 bash iso windows bootable uefi
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
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}"
Run Code Online (Sandbox Code Playgroud)
该dumpet输出指示原始包含两个ElTorito启动映像:一个用于BIOS样式的引导,另一个用于UEFI。使用mkisofs选项为 BIOS 指定第一个引导映像后,您需要使用-eltorito-alt-boot和-eltorito-platform efi选项指定第二个引导映像。像这样的东西:
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 \
[...]
Run Code Online (Sandbox Code Playgroud)
我不确定哪个文件可以用作 UEFI 启动映像。
更新:我得到了一个原始的 Windows 10 ISO 映像,并做了一些实验。在我的版本中,Load LBAUEFI 引导条目的值为 519。记住 CD-ROM 块大小是 2048 字节,我转储了块:
$ 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
Run Code Online (Sandbox Code Playgroud)
看起来像是 1.4 MB 软盘映像的开头。2880 个软盘扇区 * 每个软盘扇区 512 字节/每个 CD-ROM 扇区 2048 字节 = 720 个 CD-ROM 扇区。我猜固件只是忽略了该Load Sectors值,并查看 FAT 引导扇区以找到实际大小。
dd if=<silly_long_name>.iso bs=2048 skip=519 count=720 of=win_efi_boot.img
Run Code Online (Sandbox Code Playgroud)
是的,它包含一个 (v)FAT12 文件系统,只有一个文件:\EFI\BOOT\BOOTX64.EFI,大小为 936352 字节。
$ 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
Run Code Online (Sandbox Code Playgroud)
我还对win_efi_boot.img文件进行了十六进制转储:在文件结束后BOOTX64.EFI,软盘映像的其余部分都填充了所有零字节,所以我认为这count=720是准确的。
因此,您应该能够执行相同的操作以从原始 ISO(如我的win_efi_boot.img)中翻录 UEFI 引导文件系统映像,并将其与您的-e选项一起使用。
小智 3
为了扩展和描述 @telcoM 上面提供的有用信息,我提供了这个过程,它使我获得了一个可用的(即 EFI 可启动的Wn10_20H2_v2_English_x64.iso)ISO。我的目的是分割该install.wim文件,以便允许从 FAT32 USB 驱动器安装并通过Ventoy进行简单的 ISO 使用。
快速概述:
mkisofs问题wim存档boofx64.efi其中包含的文件似乎与目录中的文件efi/boot/不同剧本:
#!/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"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3418 次 |
| 最近记录: |