설치 ISO를 수정하고 부팅 가능한 상태로 유지하는 방법은 무엇입니까?

설치 ISO를 수정하고 부팅 가능한 상태로 유지하는 방법은 무엇입니까?

비슷한 질문이 많다는 것을 알고 있지만 충분히 구체적이지 않습니다.

Windows 10 x64 설치 ISO가 있고 파일을 추출하고 일부 수정한 다음 추출/수정된 파일에서 새 ISO를 만들려고 합니다.

기본적으로 잘 작동하지만 문제는 UEFI를 다시 부팅 가능하게 만드는 방법을 모른다는 것입니다(레거시/BIOS 모드에서는 제대로 부팅됩니다).

이 작업을 수행하는 방법에 대한 지침이 포함된 수많은 게시물을 읽었지만 그중 어느 것도 내 Windows 10 ISO에서 작동하지 않습니다. 이러한 게시물의 대부분은 이전 버전의 Windows만 언급하고 Windows 10을 언급하는 게시물은 현재 x64 버전에서 작동할지 여부와 이 버전에서 UEFI 부팅이 가능한지 여부를 지정하지 않습니다. (확실히 나에게는 적합하지 않기 때문에 아마도 아닐 것입니다.)

isoinfo -d -i ./windows10.iso나는 결국 및 의 출력을 최대한 많이 복제하려고 노력했습니다 .dumpet -i ./windows10.iso

이것은 내가 얻을 수 있는 가장 가까운 것입니다: (편집: -eltorito-alt-boottelcoM이 제안한 대로 업데이트됨)

원시 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

수정된 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

위 isoinfo 출력의 차이점:

$ 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

원시 ISO(덤프):

$ 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)

수정된 ISO(덤프):

$ 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)

위 덤프 출력의 차이점:

$ 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)

저는 제가 사용하고 있는 것과 동일한 ISO를 사용하여 문제를 정확하게 재현하는 스크립트를 작성했습니다.

#!/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

출력에는 dumpet원본 파일에 두 개의 ElTorito 부팅 이미지가 포함되어 있음이 표시됩니다. 하나는 BIOS 스타일 부팅용이고 다른 하나는 UEFI용입니다. 옵션을 사용하여 BIOS의 첫 번째 부팅 이미지를 지정한 후 및 옵션을 사용하여 두 번째 부팅 이미지를 지정 mkisofs해야 합니다 . 이 같은:-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 \
  [...]

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

1.4MB 플로피 이미지의 시작 부분처럼 보입니다. 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

예, 여기에는 파일 크기가 936352바이트인 (v)FAT12 파일 시스템이 포함되어 있습니다 \EFI\BOOT\BOOTX64.EFI.

$ 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

나는 또한 파일의 16진수 덤프를 가져왔습니다 win_efi_boot.img. 파일이 끝난 후 BOOTX64.EFI플로피 이미지의 나머지 부분은 모두 0바이트로 채워지기 때문에 이것이 count=720정확하다고 생각합니다.

따라서 동일한 작업을 수행할 수 있어야 하며 win_efi_boot.img원시 ISO(내 것과 같은)에서 UEFI 부팅 파일 시스템 이미지를 추출하고 옵션과 함께 사용할 수 있어야 합니다 -e.

답변2

Wn10_20H2_v2_English_x64.iso위에 제공된 @telcoM의 유용한 정보를 확장하고 설명하기 위해 사용 가능한(예: EFI 부팅 가능 ) ISO를 얻을 수 있는 이 프로세스를 제공합니다 . 내 의도는 FAT32 USB 드라이브에서 설치할 수 있도록 파일을 분할 install.wim하고 ISO를 사용하는 것입니다.벤토이.

빠른 개요:

  • 사용된교활한 도구가능한 mkisofs문제 해결
  • 사용된Wimlib분할 wim아카이브
  • TelcoM의 방법을 사용하여 ISO에서 부팅 플로피 이미지를 추출합니다. 실제 플로피 이미지를 사용하는 것이 중요해 보입니다. boofx64.efi그 안에 포함된 파일이 efi/boot/디렉터리에 있는 파일과 다른 것 같습니다.
  • ISO 빌드 프로세스는 사용자에게 플로피 이미지 LBA 및 최종 크기(항상 720 섹터)를 묻는 메시지가 표시되므로 반자동입니다.

스크립트:

#!/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" 

답변3

나는 위에서 설명한 dd 방법을 시도하는 데 오랜 시간을 보냈습니다. 그러나 이 방법은 EFI 부팅 코드를 부분적으로만 덤프하므로 EFI 부팅은 여전히 ​​실패합니다. 내가 찾은 중요한 팁:https://docs.microsoft.com/en-us/troubleshoot/windows-server/deployment/create-iso-image-for-uefi-platforms

efi의 시작 코드는 "efi/microsoft/boot/efisys.bin"에 있습니다.

이 세부 사항을 알고 나면 나머지는 쉽습니다. 특정 *nix 시스템의 mkisof 변형에 따라 약간만 다릅니다. 다음 두 가지 예를 성공적으로 테스트했으며 UEFI 보안 부팅도 작동합니다.

센트 운영 체제:

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(맥 브루):

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/"

답변4

다음 명령을 사용해 볼 수 있습니다.

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

여기에서 발췌 : http://forum.imgburn.com/index.php?/topic/24193-problem-i-can-not-create-a-uefi-bootable-iso-image/&do=findComment&comment=158044

관련 정보