使用 UEFI (OVMF) 引导时,QEMU 不遵守引导顺序

使用 UEFI (OVMF) 引导时,QEMU 不遵守引导顺序

使用qemu-system-x86_64,我希望 QEMU 启动一个带有驱动器和一些附加的虚拟 cdrom 驱动器和软盘驱动器的虚拟机。我需要它自动从第一个虚拟 cdrom 驱动器启动,而不必“按任意键从 cd/dvd 启动”。

我已经指定了 cdrom 驱动器,如下所示:

-drive "file=${WINDOWS_INSTALL_ISO},index=1,media=cdrom"

但无论我如何处理该-boot参数,它总是显示“按任意键立即从 cd/dvd 启动...”大约 5 秒钟,然后它不会从该 cd 启动。我尝试过各种事情,例如:

-boot order=d -boot menu=on

和:

-boot d

和:

-boot "order=d,menu=on"

我还尝试使用启动索引:

-drive "file=${WINDOWS_INSTALL_ISO},index=1,media=cdrom,bootindex=1"

这会导致错误:Block format 'raw' does not support the option 'bootindex'

我想要启动的 CDROM 驱动器包含 Windows 10 安装映像,我已将其配置为自动安装,无需用户交互。我的目标是拥有一个 bash 脚本,它可以自动创建 Windows VM 并自动安装 Windows,而无需任何用户交互。所以我真的只需要 QEMU 自动启动到 Windows 安装。

编辑:

我设法重现了这样的行为:

sudo qemu-system-x86_64 \
    -smp 4 \
    -m 4G \
    -drive "file=/home/fedora/vm/windows10.iso,index=1,media=cdrom" \
    -boot order=d \
    -drive id=disk0,if=virtio,cache.direct=on,if=virtio,aio=native,format=raw,file=/home/fedora/Projects/misc/MobilePassThrough/vm-files/WindowsVM.img \
    -drive "if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE.fd" \
    -drive "if=pflash,format=raw,file=/home/fedora/vm/WindowsVM_VARS.fd"

如果我删除最后两行(负责在 UEFI (OVMF) 模式而不是 BIOS (SeaBIOS) 模式下启动),那么它实际上会尊重该-boot参数。但我必须以 UEFI 模式启动虚拟机,否则对我来说就没用了。

编辑2:如果我理解正确的话,在 UEFI 世界中,启动顺序是由保存在非易失性存储中的变量决定的(在我的例子中为“home/fedora/vm/WindowsVM_VARS.fd”)。现在,当启动失败时,我想我会进入“UEFI shell”。经过一些研究后,该 shell 似乎是通过 QEMU 的串行端口公开的,理论上必须可以通过“setvar”和“expect”设置变量。但我也不知道该变量的名称是什么,也不知道其值会是什么样子,或者我什至不知道如何在其中指定我的 CD 驱动器。我什至不知道“setvar”和“expect”是如何工作的。

答案1

如果使用 /usr/share/OVMF/OVMF_VARS.fd 的新副本使用这些参数启动 QEmu,它应该自动启动 CD:

-drive file=${WINDOWS_INSTALL_ISO},format=raw,if=none,media=cdrom,id=drive-cd1,readonly=on \
-device ahci,id=achi0 \
-device ide-cd,bus=achi0.0,drive=drive-cd1,id=cd1,bootindex=1

(这些取自脚本中qemu-ovmf-secureboot,它从 Python 脚本启动 UefiShell.iso 并通过管道向其提供命令)。第一行添加设备,第二行添加适配器,第三行将设备连接到适配器。

但是,Windows 安装程序本身会显示消息“按任意键从 CD 或 DVD 启动”,如果超时则继续启动(这将导致进入 EFI Shell)。这样做最初是为了防止在计算机第一次重新启动时再次运行安装,并且我相信即使介质上有 autounattend.xml 文件,也会发生这种情况。

在问题中Windows 无需按任何键即可启动 iso 文件,提到CD上的目录efisys_noprompt.bin中存在一个可以代替efisys.bin的文件。EFI\Microsoft\Boot您可以将其作为安装介质配置的一部分来执行。

如果您有不修改 ISO 的硬性要求,您可以尝试创建一个仅包含 AutoUnattend.xml 和 EFI 分区的小映像,然后使用 bcdedit 修改启动数据库以EFI\Microsoft\Boot\BCD设置 ramdisksdidevice 启动加载程序选项加载安装程序从CD(我不知道这是否真的有效;我还没有尝试过)。

-no-reboot安装时使用QEmu的选项;当机器重新启动时,它将返回到您的脚本;然后您可以第二次使用不同的引导索引再次启动它。

要将 bootindex 与硬盘一起使用,您可以将其添加到 QEmu,如下所示:

-drive file=${TARGET_IMAGE},format=raw,if=none,media=disk,id=drive-hd1,readonly=off \
-device virtio-scsi-pci,id=scsi0 \
-device scsi-hd,bus=scsi0.0,drive=drive-hd1,id=hd1,bootindex=2

(这个适配器当然需要虚拟IO安装了 RedHat 的驱动程序)

答案2

我已按照您在 Edit2 上的提示进行操作,这就是我的发现。

实际上,-boot [order=drives][,once=drives] ...选项仅指 BIOS/Legacy 引导。如果你检查QEMU 的文档在此选项中,您会看到它没有对 EFI 做出任何评论。

要改变 QEMU 上的 EFI 启动行为,您必须编辑该VM_VARS.fd文件,如果我理解正确的话,相当于包含 EFI 标准上指定的启动参数的闪存 SPI 存储器。你可能可以VM_VARS.fd直接编辑,但老实说我没有研究过这种方法;我改用 UEFI Shell。以下是我采取的步骤:

1)复制默认配置。

`$ cp /usr/share/OVMF/OVMF_VARS.fd ~/my_vars.fd`

2) 运行 QEMU 并访问 UEFI Shell。

就我而言,我想从 SATA 设备启动,因此-drive id=disk ...接下来的设置对于我的设置来说是特定的,您应该更改为您需要的内容。

sudo qemu-system-x86_64 \
          -cpu host --enable-kvm \
          -drive "if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE.fd" \
          -drive "if=pflash,format=raw,file=~/my_vars.fd" \ 
          \
          -drive id=disk,file=fat:rw:rootfs,if=none \
          -device ich9-ahci,id=ahci \
          -device ide-drive,drive=disk,bus=ahci.0 \
          -nographic \
          -no-reboot \

等待它回退到 UEFI Shell。如果最初尝试通过网络启动,可能需要几分钟的时间。你最终会来到这里:

UEFI Interactive Shell v2.2
EDK II
UEFI v2.70 (EDK II, 0x00010000)
Mapping table
      FS0: Alias(s):HD1a65535a1:;BLK3:
          PciRoot(0x0)/Pci(0x4,0x0)/Sata(0x0,0xFFFF,0x0)/HD(1,MBR,0xBE1AFDFA,0x3F,0xFBFC1)
     BLK0: Alias(s):
          PciRoot(0x0)/Pci(0x1,0x0)/Floppy(0x0)
     BLK1: Alias(s):
          PciRoot(0x0)/Pci(0x1,0x0)/Floppy(0x1)
     BLK2: Alias(s):
          PciRoot(0x0)/Pci(0x4,0x0)/Sata(0x0,0xFFFF,0x0)

Press ESC in 1 seconds to skip startup.nsh or any other key to continue.
Shell> 

你可以参考这个广泛的清单EFI Shell 命令或任何其他 UEFI 文档。我找到了这个文章Arch 非常有帮助;它展示了如何添加、删除和移动启动项。

3)修改启动项。你可能会运行类似的东西:

Shell> bcfg boot add 0 FS0:\EFI\boot\BOOT_X64.efi "my_boot"

分解:

bcfg boot add- 添加新的启动项。

0- 在哪里插入(0 是第一个)。

FS0:\EFI\boot\BOOT_X64.efi- [device_mapping]:[路径/到/efi/payload/in/device]。使用该map命令列出映射。请注意,FS0 是我的 SATA 设备。

"my_boot"- 您的条目的别名。

就是这样。您的修改将保存在my_vars.fd.不要忘记将其添加到所有后续的 QEMU 调用中。

答案3

也许在来宾中从 CD-ROM / DVD-ROM 手动启动一次会有所帮助:

  • 等待 TianoCore 启动屏幕出现
  • 按 ESC 键
  • 使用启动管理器选项从 DVD-ROM 启动

答案4

根据fedoraproject.org/wiki您需要“UefiShell.iso”才能启动进入 UEFI shell。

由于 OVMF 未附带安装任何 SecureBoot 密钥,因此我们需要安装一些密钥来模仿 MS 认证的 UEFI 计算机附带的内容。 OVMF 现在附带设置默认密钥集所需的二进制文件。最简单的方法是使用 /usr/share/edk2/ovmf/UefiShell.iso 中提供的 UefiShell.iso。使用此文件作为 CD-ROM 映像启动您的虚拟机,它应该启动到 UEFI shell。根据提示。

相关内容