- 由 虚拟的现实创建于11月 23, 2024 需要 2 分钟阅读时间
简介
几乎每个桌面 Linux 用户都有运行 Windows 程序的需求,解决方案也五花八门。本文所述方案以 稳定易用 为首要目标:
- QEMU (KVM) + 精简版 Win10。WebDAV 文件共享。
- 使用 Snapshot 避免写入原始镜像。
与其他方案对比
对比 Wine:
- Wine 性能好;本方案图形性能较弱。
- 本方案较为通用,可在各种硬件、内核、发行版下运行;Wine 对环境要求较多。
- 本方案几乎无需维护,一劳永逸;Wine 有时需为特定应用作出调整,存在紧急情况下新应用无法运行的尴尬。
对比其他虚拟机:
- VitrualBox 图形性能略好,但需额外加载内核模块;本方案使用 KVM,更稳定。
- ESXi 综合性能较好,但安装繁琐,收费;本方案安装简便,除 Windows 本身外完全开源。
- 本方案中 QCOW2 磁盘镜像支持 ZSTD 压缩,体积小(当前为 1.33 GiB)
配置使用
下载链接: OneDrive | 百度网盘 。若无特殊需求,建议直接使用成品镜像。其中 win10_xxx.qcow2 是磁盘镜像主体,文件名后半段为 CRC32 值;cd.iso 是外置镜像,包含 WebDAV 服务端;win10_xxx_dev.qcow2 是包含常用编译工具链和 Office 的差分镜像。
安装 QEMU
# Ubuntu apt install qemu-kvm qemu-utils # Fedora dnf install qemu-system-x86 # Fedora 精简安装 dnf install qemu-system-x86-core qemu-ui-gtk qemu-audio-pipewire qemu-device-usb-host qemu-img dnf install qemu-device-display-virtio-gpu qemu-device-display-virtio-gpu-gl qemu-device-display-virtio-vga qemu-device-display-virtio-vga-gl
写入并运行 ./win10(.sh):
#!/bin/sh base_img=qemu_win10/win10_xxx.qcow2 snapshot_img=qemu_win10/win10_snapshot.qcow2 # 可以考虑放进 /tmp share_img=qemu_win10/cd.iso [ ! -e $snapshot_img ] && qemu-img create -q -F qcow2 -b $base_img -f qcow2 $snapshot_img qemu-system-x86_64 \ -machine q35,accel=kvm -cpu host,hv-relaxed,hv-vapic,hv-spinlocks=0x1fff,hv-vpindex,hv-time,hv-synic,hv-stimer -rtc base=localtime \ -smp 2 -m 1.5G \ -hda $snapshot_img -cdrom $share_img \ -nic hostfwd=tcp:127.0.0.1:9121-:5000 \ -display gtk,gl=on -device virtio-vga-gl -device qemu-xhci -device usb-tablet \ $*
启动后使用任意 WebDAV 客户端连接 dav://127.0.0.1:9121/,实现文件共享。nautilus 内置的就行,左侧栏 Other Locations > 底部 Connect to Server。
其他常用命令行选项
# USB 直通(使用 lsusb 获取两个 id) -device usb-host,vendorid=0x0000,productid=0x1111 # 音频支持 -audiodev pipewire,id=pw0 -device usb-audio,audiodev=pw0 # 也许可以少点东西,没必要 -no-user-config -nodefaults
详细信息
- 集成常用运行库和精简版输入法。自定义内容建议写入外置镜像。
- 未激活,个人认为不影响使用。
- 默认 Administrator 用户,禁用几乎所有安全功能,强制自动登录。
- 制作于 QEMU 6.2,经测试 8.2 可用,之后应该也没问题。
- 如何自动修改 DPI 和屏幕分辨率:外置镜像中有示例代码。
- 触摸板无法平滑滚动:在 Win 中调整滚轮速度为每次 1 行,可以缓解问题。
- 为什么使用中文版系统:有些国内软件在非中文环境下会卡 Bug。也许可以换用 Tiny10。
- 为什么不使用 virt-manager:本文同样适用,只是个人认为直接使用 QEMU 更便捷。
减小磁盘镜像体积
对减小镜像体积的问题,当前网络上有许多过时甚至错误的内容,所以在这说道两句。下述内容中如非注明,都是指装有 Windows 系统的虚拟机磁盘镜像。
收缩与压缩
文件系统的设计非常复杂(正经点,别拿 tmpfs 说事):删除文件,会留下空洞;多个 fd 同时写入,可能产生碎片;想减少碎片产生,需要预分配;为提升性能,还可能缓存写入队列,先规划一下再 commit...
磁盘镜像驱动本质是一个用户态的文件系统后端,把对块设备的操作映射到文件。客户机文件系统与宿主机之间缺乏信息共享,导致了各种问题:空洞难以被积极回收,碎片与预分配过度占用之间的权衡等。所以我们需要偶尔执行收缩、压缩这类高开销操作。
请一定区分“收缩(shrink)”与“压缩(compress)”。“收缩”是整理镜像,消除空洞、碎片、冗余数据;“压缩”则是将数据使用压缩算法进行处理。
许多教程推荐用 Virtual Disk Precompactor 或 dd 撑满分区,迫使客户机文件系统腾出连续空间,但这类做法实际上非常糟糕:需写入大量数据,耗时长;不能同时 defrag,效果差。收缩镜像最简单有效的方式是取出内容写入新镜像。可以使用 Dism++ 等工具备份系统分区,还原到新镜像上:
qemu-img create -f qcow2 win10.qcow2 32G # > 此时安装系统 mv win10.qcow2 win10.old.qcow2 qemu-img create -f qcow2 win10.qcow2 32G # > 此时启动到 PE,拆分原镜像分区,备份到拆出的空闲分区,还原到新镜像的分区 rm win10.old.qcow2 # 可选,差异不明显。如果你接下来还要压缩,那么这一步是**完全多余**的 # qemu-img convert -p -f qcow2 -O qcow2 -c win10.qcow2 win10-shrink.qcow2
对于压缩,若你在客户机内使用 NTFS 压缩,就会发现这毫无作用,因为它会尽量减少搬运,导致压缩后数据依然是稀疏分布的。个人认为目前最佳方案是在 QCOW2 上启用 ZSTD 压缩:
qemu-img convert -p -f qcow2 -O qcow2 -c -o compression_type=zstd,preallocation=off win10.qcow2 win10-zstd.qcow2
相比于客户机内的 NTFS 压缩,QCOW2 的解压完全在宿主机上运行,性能损失较小。进一步地,我们还可以 修改 QCOW2 镜像的 ZSTD 压缩级别,尽力压到最小。
快照
Windows 的可控性向来都很糟糕。若你有幸打开过 UWF,就会观察到各个进程在各种角落不断写入临时文件。我们不可能找到所有这些地方并定时清理。
使用 Snapshot 是比较好的方案:随时回滚,遏制镜像体积膨胀,在出现意外后兜底。
qemu-img create -q -F qcow2 -b win10_xxx.qcow2 -f qcow2 win10_snapshot.qcow2 # qemu-kvm -hda win10_snapshot.qcow2 -cpu host -accel kvm -smp 2 -m 2G
你还可以创建共用同一 Backing 的多个 Snapshot。在一段时间后若 Snapshot 体积增大,按照上文的方法进行压缩即可。
- 无标签
0 评论