云萧的咕咕屋

以万象之不息,致不息之万象

博主头像
云萧是个咕咕怪
大一狗,在前端路上奋斗的人类
18
文章
4
分类
7
标签
本页内容

在QEMU安装Windows on ARM
在QEMU安装Windows on ARM
本文详细介绍如何在 QEMU 虚拟机中安装 Windows on ARM,包括所需工具、环境配置、镜像下载、UEFI 固件设置及 VirtIO 驱动安装等步骤,帮助用户成功运行 WoA 系统。
2023-12-23 15 分钟 6474 字 折腾

前言

<> 里的内容是需要自行修改的内容,修改时需要将 <...> 以内的东西修改掉

/Index:<序号>,修改为 /Index:1

准备工具

推荐使用

推荐使用我提供的工具,但是不包含系统镜像,大部分工具已不可下载,我还可以提供现有的备份以供使用

OneDrive

Windows ARM 镜像

将下载好的 Windows ARM 镜像文件,放入到“存放文件夹”

QEMU

安装 QEMU 时需要记住安装路径,安装完成后需要[添加到 PATH 环境变量]

UEFI 固件

Fedora 与 QEMU 提供的 edk2 固件无法正常使用,故使用 kraxel 的 edk2-git 固件构建(存档)

Linaro Releases

OneDrive

下载完成后打开压缩包,定位到路径:edk2.git-aarch64-0-20220719.209.gf0064ac3af.EOL.no.nore.updates.noarch.rpm\edk2.git-aarch64-0-20220719.209.gf0064ac3af.EOL.no.nore.updates.noarch.cpio\.\usr\share\edk2.git\aarch64,将里面的 QEMU_EFI.fdvars-template-pflash.raw 解压出来到“存放文件夹”

VirtIO 驱动光盘

最新版下载链接

将下载好的文件,放入到“存放文件夹”

配置 QEMU 环境变量

按下 WIN + R 以打开“运行”,输入 SystemPropertiesAdvanced.exe 并按下 ENTER 以回车 在弹出的“高级系统设置”程序里,点击“环境变量”

在“系统变量”里找到名为 Path 的项并双击,点击旁边的“新建”,最后在矩形框中输入 QEMU 的安装目录

最后,全部点击“确定”即可

创建硬盘文件

输入如下命令来创建硬盘文件

qemu-img.exe create -f <硬盘格式> "<存放路径\文件名.硬盘格式>" <容量大小><单位>

比如我存放在“存放文件夹”,文件名为 OS,硬盘格式为 qcow2,容量大小为 80 GB

那么我的命令如下(需要区分大小写,而且路径和文件名最好不要有空格,用下划线 _ 来代替):

qemu-img.exe create -f qcow2 "E:\VMs\WoA11\OS.qcow2" 80G

若没有别的错误则创建成功

创建 VHD(X) 而不是使用以上硬盘格式

使用 VHDX 或 VHD 的好处是可以直接挂载到文件资源管理器,简单地操作里面的文件,性能更好,也可以挂载后直接使用 Dism++ 应用系统,安装完成后再启动到虚拟机

管理虚拟硬盘 (VHD) | Microsoft Learn

编写启动脚本

在“存放文件夹”下,创建一个文本文档,并将其重命名为 Start.cmd

至此,“存放文件夹”下的文件都有:

E:\VMs\WoA11
├─ OS.qcow2
├─ QEMU_EFI.fd
├─ Start.cmd
├─ vars-template-pflash.raw
├─ virtio-win-0.1.285.iso
└─ zh-cn_windows_11_consumer_editions_version_26h1_arm64_dvd_900d64ce.iso

文件解释
  • OS.qcow2:硬盘文件
  • QEMU_EFI.fd:UEFI 固件代码镜像(作为 “只读” pflash 设备挂载,用于虚拟机启动
  • Start.cmd:快捷启动脚本
  • vars-template-pflash.raw:UEFI 变量存储镜像(模板/可写 pflash 设备,用于保持启动项、固件变量持久化)
  • virtio-win-0.1.285.iso:VirtIO 驱动镜像
  • zh-cn_windows_11_consumer_editions_version_26h1_arm64_dvd_900d64ce.iso:系统镜像

编辑 Start.cmd,并输入如下内容

qemu-system-aarch64.exe ^
-M virt,gic-version=3 ^
-cpu <CPU 型号> ^
-smp <逻辑总数>,sockets=<插槽数>,cores=<核心数>,threads=<线程数> ^
-m <运行内存> ^
-accel tcg,thread=multi ^
-device qemu-xhci ^
-device usb-kbd ^
-device usb-tablet ^
-drive file="<存放文件夹\硬盘文件名.qcow2>",if=virtio ^
-nic user,model=virtio ^
-drive file="<存放文件夹\系统镜像文件名.iso>",media=cdrom,if=none,id=cdrom0 ^
-device usb-storage,drive=cdrom0 ^
-drive file="<存放文件夹\virtio-win 名称.iso>",media=cdrom,if=none,id=cdrom1 ^
-device usb-storage,drive=cdrom1 ^
-bios "<存放文件夹\QQEMU_EFI.fd>" ^
-device ramfb ^
-drive file="<存放文件夹\vars-template-pflash.raw>",if=pflash,index=1,format=raw
重要提示,必看内容

特别注意:自 Windows 11 24H2 采用 Rust 重写 Windows 内核文件后,所模拟的 SoC 需要为 ARMv8.1 及以上(即支持新的原子操作指令),否则将无法启动;不支持新的原子操作指令的 SoC 最高可启动的 Windows 版本为:Windows 11 Build 25163

Windows 11 build 25163 is the last one than can boot on the Raspberry Pi 4 and older.

Recent insider builds no longer work as they make extensive use of the new atomic instructions introduced in ARMv8.1.[3]

关于硬件的选择
  1. QEMU 查询可用的硬件命令
    • 查询支持模拟的主板:qemu-system-aarch64.exe -M help
    • 查询支持模拟的 CPU:qemu-system-aarch64.exe -cpu help
  2. 对于 Windows ARM64,可用的 CPU 型号:
    • Cortex 系列:cortex-a76cortex-a72cortex-a57cortex-a53(最成熟、测试最充分的模型)
    • max(向虚拟机暴露 QEMU 当前版本支持的所有 AArch64 指令集特性),使用 max 时推荐添加 ,pauth=off 以禁用指针验证,在纯软件模拟 (TCG) 下,这会导致 CPU 为了验证每一个跳转指令而产生海量的计算开销,经常导致内核初始化超时而卡死
    • Neoverse 系列:neoverse-n1 和 neoverse-v1(专为服务器设计的架构)
  3. 若要开启嵌套虚拟化,请将 -M virt 修改为 -M virt,virtualization=true(不推荐开启,避免增加性能消耗)
  4. gic-version=3 开启 ITS 能显著提高 I/O 稳定性
  5. -smp 表示任务管理器可以显示多少个框框,sockets 表示有多少 CPU 插槽(推荐只设置为 1 以只设置 1 个 CPU 数,以避免 SKU 检查与性能损失),cores 表示 CPU 核心数量,threads 表示支持的线程数(推荐只设置为 1 以关闭超线程,减少性能损耗)
    • 计算公式为:总核心数 (smp) = sockets * cores * threads
  6. -accel tcg,thread=multi 为 QEMU 2.9 及之后的版本提供多核翻译支持
  7. 若想要免驱的网卡,请使用 -netdev user,id=net0 ^-device e1000e,netdev=net0 ^,而不是 -nic user,model=virtio ^

比如我的 CPU 型号为 max CPU 逻辑总数为 4,插槽数为 1,核心数为 4,线程数为 1,运行内存大小为 6144 MB 那么我的命令如下:(需要区分大小写,而且路径和文件名最好不要有空格,用下划线 _ 来代替)

qemu-system-aarch64.exe ^
-M virt,gic-version=3 ^
-cpu max,pauth=off ^
-smp 4,sockets=1,cores=4,threads=1 ^
-m 4096 ^
-accel tcg,thread=multi ^
-device qemu-xhci ^
-device usb-kbd ^
-device usb-tablet ^
-drive file="E:\VMs\WoA11\OS.qcow2",if=virtio ^
-nic user,model=virtio ^
-drive file="E:\VMs\WoA11\zh-cn_windows_11_consumer_editions_version_26h1_arm64_dvd_900d64ce.iso",media=cdrom,if=none,id=cdrom0 ^
-device usb-storage,drive=cdrom0 ^
-drive file="E:\VMs\WoA11\virtio-win-0.1.285.iso",media=cdrom,if=none,id=cdrom1 ^
-device usb-storage,drive=cdrom1 ^
-bios "E:\VMs\WoA11\QEMU_EFI.fd" ^
-device ramfb ^
-drive file="E:\VMs\WoA11\vars-template-pflash.raw",if=pflash,index=1,format=raw

保存后,双击 Start.cmd 以启动虚拟机

修改分辨率

在启动阶段,按下 ESC 以进入 UEFI 固件设置

进入固件设置后,选择 Device Manager

选择 OVMF Platform Configuration

Change Preferred Resolution for Next Boot 中,将分辨率修改为 1024x768

完成后,按下 F10 以保存设置,按下 Y 确认保存,随后按下两次 ESC 以退出固件设置,选择到最下方的 Reset 以重启虚拟机

安装系统

经过漫长的等待后就可以进入系统了

Windows 安装程序

等待几分钟,虚拟机会自动进入到 Windows 安装程序

在选择磁盘的时候,点击“加载驱动程序”

点击“浏览”

选择 VirtIO-Win 光驱,找到名为 viostor 的文件夹,选择里面 w11 文件夹下的 ARM64 文件夹(如果安装的是 Windows 10 则选择 w10,以此类推)

选择驱动程序,点击“安装”,这样就可以正常加载磁盘了

随后,即可开始安装 Windows

部署系统

系统会经历两次重启,我在 NVMe 上用了约一个小时才从 Windows 安装程序进入到 OOBE

“请稍等…”阶段等待几分钟,当微软输入法工具栏出现之后,再等待几分钟即可进入到 OOBE

由于我们暂时没有安装网卡驱动,所以需要跳过联网,详情请参阅:跳过 Windows 激活联网要求

“请稍等…”阶段等待几分钟,当微软输入法工具栏出现之后,再等待几分钟即可进入到 OOBE

若无法跳过账户登录或只能登录到工作账户

若发现只能登录到工作账户,请按下 Ctrl + Shift + F3 以跳过 OOBE

在“计算机管理”里启用 Administrator 或新建其他管理员账户,随后以管理员身份运行 CMD 并输入命令:

xcopy "%SystemRoot%\System32\oobe\audit.exe" "%Public%\Desktop\Backup" /X
xcopy "%SystemRoot%\System32\svchost.exe" "%SystemRoot%\System32\oobe\audit.exe" /X

完成后重启虚拟机即可


完成 OOBE 后,就会开始准备桌面与用户配置

至此,系统就安装完成了

安装网卡驱动

右键“开始”菜单,选择“终端(管理员)”、“Windows PowerShell(管理员)”或“命令提示符(管理员)” 输入以下命令以开启“测试模式”,并重启

bcdedit /set testsigning on

关于加载已进行测试签名的驱动程序,请参阅:允许加载已进行测试签名的驱动程序 - Windows drivers | Microsoft Learn

重启之后,在文件资源管理器里打开 VirtIO-Win 光驱,定位到 \NetKVM\w11\ARM64(如果是 Windows 10 就选择 w10 文件夹,以此类推)

右键类型为“安装信息”的 netkvm 文件,选择“安装”

使用体验

无比慢,特别慢,非常慢,巨慢,受到一些限制,x64 的还不能很好地转译到 ARM64

后记

  1. 性能与显示
    因为没有显卡驱动以及其他的驱动,在 QEMU 模拟 Windows ARM 性能会大打折扣,整个过程会非常漫长,建议将文件存放在 SSD 内
    如果你会添加驱动的话,可以修改 install.wiminstall.esdboot.wim,向内添加了 VirtIO 驱动之后再添加如下参数到 Start.cmd 以支持 virtio-gpu 输出
-device virtio-gpu-pci,virgl=on ^
-display gtk,gl=on ^
  1. 光驱管理
    如果你后面不需要光驱了可以把如下内容删除
-drive file="<存放文件夹\系统镜像文件名.iso>",media=cdrom,if=none,id=cdrom ^
-device usb-storage,drive=cdrom ^
-drive file="<存放文件夹\virtio-win 名称.iso>",media=cdrom,if=none,id=cdrom1 ^
-device usb-storage,drive=cdrom1 ^
  1. 驱动管理
    文章内仅模拟了所需的硬件及网卡,其他的硬件需要自行查询
    镜像内其他驱动的大致意思如下:[4]

    • NetKVM: Virtio 网络驱动
    • viostor: Virtio 块驱动
    • vioscsi: Virtio SCSI 驱动
    • viorng: Virtio RNG 驱动
    • vioser: Virtio 串口驱动
    • Balloon: Virtio 内存气球驱动
    • qxl: 用于 Windows 7 及之前版本的 QXL 显卡驱动(virtio-win-0.1.103-1 和之后版本会创建)
    • qxldod: 用于 Windows 8 及之后版本的 QXL 显卡驱动(virtio-win-0.1.103-2 和之后版本会创建)
    • pvpanic: QEMU pvpanic 设备驱动(virtio-win-0.1.103-2 和之后版本会创建)
    • guest-agent: QEMU Guest Agent 32bit 和 64bit 安装包
    • qemupciserial: QEMU PCI 串口设备驱动
    • vfd: 用于 Windows XP 下的 VFD 软驱镜像
  2. 优化 尝试 BetaWiki 给出的解决方案以关闭打印机、磁盘整理与休眠

sc.exe stop "Spooler"
sc.exe config "Spooler" start= disabled
sc.exe stop "WSearch"
sc.exe config "WSearch" start= disabled
schtasks.exe /Delete /TN "\Microsoft\Windows\Defrag\ScheduledDefrag" /F
powercfg.exe -h off
  1. 传输文件 在物理机内添加共享文件夹,权限改成 Everyone 并允许读取写入(如果你怕会被其他人截取则在映射网络驱动器时需要输入物理机的系统账户以登录到共享文件夹),然后在虚拟机内映射网络驱动器即可

  2. PE 或 Setup 加载驱动 在 PE 或 Setup 下,可以使用 drvload 命令来加载驱动

更多关于 Devload 的命令,请参阅 Drvload 命令行选项 | Microsoft Learn

drvload "path\to\fileName.inf"

示例如下(可使用 treedir 命令来列出文件夹内容)

drvload "E:\viostor\w11\ARM64\viostor.inf"

参考文献

在QEMU安装Windows on ARM

https://blog.crrashh.com/posts/11-qemu-woa.html

除特殊声明转载之外,本文由博主云萧原创且非 AI 生成内容,依据 CC BY-SA 4.0 许可协议授权,若需转载请注明出处及本声明。

尚未开启评论功能,敬请期待