Windows 10 UEFI 物理到 KVM/libvirt 虚拟

Mat*_*att 5 linux-kvm uefi p2v windows-10

原帖

我正在将我的 PC 从 Windows 10 迁移到 Linux。有一些事情我仍然需要 Windows,而且我目前正在双引导,Windows 和 Linux 位于不同的物理磁盘上。我想摆脱双引导,并在 KVM+libvirt+qemu 下运行虚拟化的 Windows 10 安装。

这里棘手的部分似乎是我的 Windows 10 安装是通过 UEFI(使用 GPT 分区表)完成的,而不是传统的 BIOS MBR。这是我的 Windows 磁盘的样子:

$ sudo parted /dev/nvme0n1 print
Model: Unknown (unknown)
Disk /dev/nvme0n1: 500GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start   End    Size    File system  Name                          Flags
 1      1049kB  524MB  523MB   ntfs         Basic data partition          hidden, diag
 2      524MB   628MB  104MB   fat32        EFI system partition          boot, esp
 3      628MB   645MB  16.8MB               Microsoft reserved partition  msftres
 4      645MB   500GB  499GB   ntfs         Basic data partition          msftdata
Run Code Online (Sandbox Code Playgroud)

由于它被设置为 UEFI,似乎需要一些额外的步骤来进行虚拟化,因为 libvirt 似乎并不支持 UEFI 开箱即用。我尝试的是将上述每个分区导出为 qcow2 映像,使用如下命令:

$ qemu-img convert -f raw -O qcow2 /dev/nvme0n1p1 win10_part1.qcow2
Run Code Online (Sandbox Code Playgroud)

并重复所有四个分区。然后我在 virt-manager 下创建了一个虚拟机,导入所有四个 qcow2 驱动器。我为我的发行版 (Manjaro) 安装了“ovmf”包,并将这一行添加到虚拟机的 XML 配置文件的“os”部分:

<loader type='rom'>/usr/share/ovmf/x64/OVMF_CODE.fd</loader>
Run Code Online (Sandbox Code Playgroud)

当我启动虚拟机时,我看到了 TianoCore 启动画面。但它只会让我进入 grub2 shell,而不是找到 Windows 引导加载程序。

我还尝试从 Windows 10 安装 ISO 启动此 VM,希望我可以“修复”系统以启动。但这没有用。

我确定我错过了一些东西。更好的是将其转换为 MBR 引导,以避免 OVMF 依赖性。

编辑/更新...

根据 Dylan 的评论,我确实让它工作了,但是一路上出现了一些小问题,我想我会把它们张贴在这里以防其他人有类似的问题。

正如 Dylan 所写,第一步是创建整个磁盘的映像,而不是每个分区的单个磁盘。我使用了这个命令:

qemu-img convert -f raw -O qcow2 /dev/nvme0n1 win10_import.qcow2
Run Code Online (Sandbox Code Playgroud)

然后我在 virt-manager 中创建了虚拟机,将上面的磁盘映像(“win10_import.qcow2”)指定为我的驱动器。

接下来是使用 OVMF (TianoCore) UEFI 固件。这是通过安装 ovmf 包(Manjaro 上的“ovmf”),然后将其添加到虚拟机的 XML 定义来完成的:

  <os>
    <type arch='x86_64' machine='pc-q35-3.0'>hvm</type>
    <loader type='rom'>/usr/share/ovmf/x64/OVMF_CODE.fd</loader>
  </os>
Run Code Online (Sandbox Code Playgroud)

之后,Windows仍会在启动期间崩溃,出现蓝屏和错误“系统线程异常未处理”。出于某种原因,它不喜欢“复制主机 CPU 配置”CPU 设置。我改为“core2duo”,然后启动。现在我正在使用“SandyBridge”,这也有效。(就其价值而言,我确实创建了另一个独立的 Win10 VM,从头开始进行全新安装。 VM 确实使用了“复制主机 CPU 配置”。我的 CPU 是 AMD Ryzen 5 2400G。)

我遇到的下一个问题是 Windows 10 运行速度慢得难以忍受。不知何故,我设法使用“QEMU TCG”虚拟机管理程序而不是“KVM”创建了虚拟机。这是有道理的,因为前者是模拟并且非常慢,而后者是真正的硬件辅助虚拟化。(这是怎么发生的:在尝试让它工作时,我还在物理系统上进行了 BIOS 升级,这重置了我的所有 BIOS 设置,其中一个禁用了虚拟化(在我的 BIOS 中称为“SVM”)。一旦我纠正了这个,我能够使用接近本机的速度 KVM 管理程序。)

下一个问题是屏幕分辨率停留在 800x600。Windows 不会让我改变它。我可以在机器启动后立即按Esc进行一次性修复,就在 TianoCore 飞溅出现时。这让我进入 UEFI 设置,在那里我可以强制提高分辨率。但这不是永久修复。

由于我的虚拟机将 QXL 指定为视频设备,因此我需要在 Windows 中安装 QXL 驱动程序。这个页面,使用 virtIO 驱动程序创建 Windows 虚拟机解释了如何做到这一点。简短版本是这样的:在主机上下载virtio-win iso。将其作为 CD-ROM 驱动器添加到 VM。然后,启动到 VM,导航到 CD-ROM 上的正确文件夹,并安装所有需要的 VirtIO 驱动程序。具体来说,对于 Windows 10 上的 QXL 视频,“qxldod”文件夹具有正确的驱动程序。

小智 1

QEMU/Libvirt 希望您提供虚拟磁盘:您的 QCOW2 文件应该是磁盘而不是分区。通过执行您所做的操作,您获得了 4 个 qcow2 文件,每个文件都有一个分区。你打破了以前的结构,GRUB 无法再引导你的系统也就不足为奇了。

我建议您将整个物理驱动器转换为单个 QCOW2 文件,然后将此虚拟驱动器附加到您的虚拟机。

您应该能够从 EFI 分区中删除 GRUB EFI 文件(请参阅 libguestfs 工具)并使用启动菜单,因为 Windows 启动加载程序应由 VM 的 UEFI 加载。