当您启动Windows 10 ISO时,您将得到以下误导性提示:
为什么会有误导?因为这条消息来自Windows本身,您实际上已经从它启动了。此提示符是一项功能,可以防止您意外地在Windows映像中启动。
现在我有了一个非常具体的用例,在这个提示符中,我无法自动创建和安装一个基于UEFI的Windows 10 VM。
因此,我已经做了一些调查,在Windows上,您可以通过在引导条目上指定一个noprompt
映像来创建一个没有提示符的Windows,如下所示:
$setfsboot="C:\01_TEMP\ISO\etfsboot.com"
$sefisys ="C:\01_TEMP\ISO\efisys_noprompt.bin"
Oscdimg -bootdata:2#p0,eb$setfsboot#pEF,e,b$sefisys -u1
-udfver102 C:\winpe_amd64\media C:\winpe_amd64\winpeamd64.iso
Quick解释
-bootdata:2#p0,eb$setfsboot#pEF,e,b$sefisys
2
意味着有两个引导条目#
分离器p0,eb$setfsboot
是默认的引导项(用于旧式BIOS启动)#
分离器pEF,e,b$sefisys
是后备引导项(用于UEFI引导)现在,我正试图在Linux上使用mkisofs实现同样的目标,这是非常棘手的,因为仅仅为了制作一个UEFI可引导的Windows,您需要上游版本的mkisofs
(参见这篇文章是mkey写的) (可以获得这里)。Linux发行版附带的mkisofs
版本显然缺乏一些特性,其中包含一些从未修复过的古老bug。
我尝试过删除efi/microsoft/boot/cdboot.efi
,然后将efi/microsoft/boot/cdboot_noprompt.efi
重命名为efi/microsoft/boot/cdboot.efi
,以欺骗ISO,但不幸的是,这并没有奏效。
目前,我使用这段代码直接从ISO提取一个引导映像:
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)"
EFI_STARTING_SECTOR="$(dumpet -i "${WIN10_IMG}" | grep "Load LBA: " | grep -o "[^:]*$" | cut -d ' ' -f2 | tail -1)"
echo "EFI_STARTING_SECTOR: $EFI_STARTING_SECTOR"
sudo dd if="${WIN10_IMG}" of="${TMP}/efi.dmp" bs=2048 count=1 skip="${EFI_STARTING_SECTOR}"
EFI_BOOT_LOAD_SIZE="$(file "${TMP}/efi.dmp" | grep -oP 'sectors (\d+)' | cut -d ' ' -f2)"
echo "EFI_BOOT_LOAD_SIZE: ${EFI_BOOT_LOAD_SIZE}"
sudo dd if="${WIN10_IMG}" of="${ISO_FILES}/efi/win_efi_boot.img" bs=2048 count="${EFI_BOOT_LOAD_SIZE}" skip="${EFI_STARTING_SECTOR}"
在上面的最后一个命令中,提取的图像放在包含从ISO提取的文件的文件夹中。
然后将-eltorito-boot "efi/win_efi_boot.img"
标志用于mkisofs
,我告诉它将其用于引导条目。
我已经写了一个脚本,自动设置您所需的一切,以达到我现在所处的位置。如果您查看脚本中的STEP 5
,您可以看到我试图更改文件名,但我想,我可能不得不更改STEP 4
,但我不知道如何更改。
#!/usr/bin/env bash
#You might have to install a few dependencies for schily tools to compile.
#On Fedora this did the trick for me: `sudo dnf install e2fsprogs-devel imake gcc-c++`
############ STEP 1 download Windows 10 ISO from Microsoft ##############
WIN10_IMG="$(pwd)/windows10.iso"
WIN10_IMG_ARCH="x64"
if [ ! -f "$WIN10_IMG" ]; then # if the windows10.iso has not been downloaded yet
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://tb.rg-adguard.net/dl.php?go=7e583fea") # This strange looking URL actually redirects to a legit software-download.microsoft.com URL
else
echo "Retrieving the x64 Windows 10 iso URL..."
WINDOWS_10_ISO_URL=$(curl -LsI -o /dev/null -w %{url_effective} "https://tb.rg-adguard.net/dl.php?go=3dd1ce66") # This strange looking URL actually redirects to a legit software-download.microsoft.com URL
fi
echo "Download URL: $WINDOWS_10_ISO_URL"
echo "Making sure the URL comes from a trusted Microsoft 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"
else
echo "URL validation failed. Please download the Windows 10 iso manually."
exit 1
fi
fi
#########################################################################
############## STEP 2 download and build the schily tools ###############
SCHILY_VERSION="2021-06-07"
SCHILY_ARCHIVE="schily-${SCHILY_VERSION}.tar.bz2"
SCHILY_DIR="./schily-tools"
if [ ! -f "${SCHILY_DIR}/mkisofs/OBJ/x86_64-linux-gcc/mkisofs" ]; then # if the mkisofs of Schily Tools has not been built yet
sudo rm -rf "${SCHILY_DIR}"
wget "https://altushost-swe.dl.sourceforge.net/project/schilytools/${SCHILY_ARCHIVE}" -O "${SCHILY_ARCHIVE}"
tar -xf "${SCHILY_ARCHIVE}"
rm "${SCHILY_ARCHIVE}"
mv "schily-${SCHILY_VERSION}" "${SCHILY_DIR}"
cd "${SCHILY_DIR}"
./Gmake.linux
cd ..
if [ ! -f "${SCHILY_DIR}/mkisofs/OBJ/x86_64-linux-gcc/mkisofs" ]; then
echo "Building Schily Tools failed"
exit 1
fi
fi
#########################################################################
################# STEP 3 Extract the files from the ISO #################
TMP="./tmp"
ISO_FILES="${TMP}/iso-files"
ISO_MP="${TMP}/iso-mountpoint"
if [ ! -f "${ISO_FILES}/setup.exe" ]; then # If the Windows ISO hasn't been extracted yet
sudo rm -rf "${TMP}"
mkdir -p "${ISO_FILES}"
mkdir -p "${ISO_MP}"
sudo mount -t udf "${WIN10_IMG}" "${ISO_MP}"
sudo cp -Rva ${ISO_MP}/* "${ISO_FILES}"
sudo umount "${ISO_MP}"
fi
#########################################################################
################## STEP 4 Extract the EFI boot image ####################
# 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)"
EFI_STARTING_SECTOR="$(dumpet -i "${WIN10_IMG}" | grep "Load LBA: " | grep -o "[^:]*$" | cut -d ' ' -f2 | tail -1)"
echo "EFI_STARTING_SECTOR: $EFI_STARTING_SECTOR"
sudo dd if="${WIN10_IMG}" of="${TMP}/efi.dmp" bs=2048 count=1 skip="${EFI_STARTING_SECTOR}"
EFI_BOOT_LOAD_SIZE="$(file "${TMP}/efi.dmp" | grep -oP 'sectors (\d+)' | cut -d ' ' -f2)"
echo "EFI_BOOT_LOAD_SIZE: ${EFI_BOOT_LOAD_SIZE}"
sudo dd if="${WIN10_IMG}" of="${ISO_FILES}/efi/win_efi_boot.img" bs=2048 count="${EFI_BOOT_LOAD_SIZE}" skip="${EFI_STARTING_SECTOR}"
#########################################################################
######## STEP 5 Make changes to the files extracted from the ISO ########
# Make some arbitrary changes to the iso files
#sudo rm -rf "${ISO_FILES}/efi/microsoft/boot/cdboot.efi"
#sudo mv "${ISO_FILES}/efi/microsoft/boot/cdboot_noprompt.efi" "${ISO_FILES}/efi/microsoft/boot/cdboot.efi"
#sudo rm -rf "${ISO_FILES}/efi/microsoft/boot/efisys.bin"
#sudo mv "${ISO_FILES}/efi/microsoft/boot/efisys_noprompt.bin" "${ISO_FILES}/efi/microsoft/boot/efisys.bin"
#########################################################################
###### STEP 6 Build a new ISO using the extracted/modified files ########
sudo rm -f "${WIN10_IMG}.tmp.iso"
sudo "${SCHILY_DIR}/mkisofs/OBJ/x86_64-linux-gcc/mkisofs" \
-no-emul-boot \
-b boot/etfsboot.com \
-boot-load-seg "${BOOT_LOAD_SEG}" \
-boot-load-size "${BOOT_LOAD_SIZE}" \
-eltorito-alt-boot \
-no-emul-boot \
-eltorito-boot "efi/win_efi_boot.img" \
-boot-load-size 1 \
-iso-level 4 \
-UDF \
-o "${WIN10_IMG}.tmp.iso" \
"${ISO_FILES}"
#########################################################################
############ STEP 7 Remove the files exxtracted from the ISO ############
#sudo rm -f "${TMP}"
#########################################################################
发布于 2021-08-05 14:46:55
您没有共享任何错误消息,说明您正在尝试失败的位置/方式。
您所做的处理UEFI引导过程的方法似乎与您说要做的事情有很长的路要走。
大多数进行大规模VM发布的地方要么使用某种预构建和验证过的模板映像来生成新的Win10实例,要么使用Windows创建的.WIM
文件执行OEM风格的无人值守安装来构建环境并选择这些选项。
您为OSCdimg链接的部分只是许可硬件制造商可用于新硬件部署的工具之一。我敢打赌,除了重新创建ISO映像之外,它在功能上肯定与linux中的efibootmgr类似。它的部分功能是对结果文件进行签名,我不明白为什么MS会在该目录中包含一个公共证书文件,允许它们在不需要网络访问的情况下对二进制文件进行签名验证。
附录:阅读了EFI规范(你也应该这么做)。您有没有想过仅仅告诉mkisofs使用-eltorito-boot efi\microsoft\boot\cdboot_noprompt.efi
,我不确定uefi想要它的目录分隔符,因为根据规范,它应该支持FAT,并且在我的编辑器中查看ISO,有一个UDF分区,这就是我获得这条路径的地方。
我从https://www.happyassassin.net/posts/2014/01/25/uefi-boot-how-does-that-actually-work-then/获得了一些很好的洞察力
https://unix.stackexchange.com/questions/660249
复制相似问题