-
Notifications
You must be signed in to change notification settings - Fork 0
Windows ARM64 VMs with QEMU
Windows ARM64 runs reasonably well in QEMU, both under KVM (on Linux ARM64 host) and TCG. Here's how I do it.
The version in Debian Bullseye seems to work well, as does version 6.1.0-2 from MSYS2 (I use the clang x86_64 variant, but that's just my preference).
The version of firmware that ships along with QEMU is rather outdated. I use a bleeding-edge firmware from debian-experimental
. At the time of writing this, it appears that there is no version currently in experimental
, but there is a version in sid
: http://ftp.us.debian.org/debian/pool/main/e/edk2/qemu-efi-aarch64_2021.08-1_all.deb
I use the AAVMF_{CODE,VARS}.ms.fd variant, which has the Microsoft keys for Secure Boot pre-loaded, and Secure Boot enabled. Note that in order to use the virtio drivers, Secure Boot needs to be disabled in the "BIOS".
Microsoft currently provides an ARM64 VHDX at https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewARM64. I use this as the base image for a virtual machine. I will document the exact version, filename, and SHA256SUM of the image I used for a release, as the delta disk version I provide requires the exact same base image.
QEMU prefers operating from a QCOW2 format disk, so I convert from VHDX to QCOW2. Example:
qemu-img convert -p -c -f vhdx Windows10_InsiderPreview_Client_ARM64_en-us_22000.VHDX -O qcow2 win11_132_official.qcow2
Then you can use the delta disk from the release, which expects that filename as its base, and create a new delta disk based on that for your OS to run in:
qemu-img create -F qcow2 -b win11_132_mod.qcow2 -f qcow2 win11.qcow2
QEMU is really not all that friendly to run out of the box (they really intend it to be used via some tool to generate the options required). Here are the commandline options I use for TCG (emulation):
#!/bin/bash
qemu-system-aarch64 \
-M virt,virtualization=true \
-accel tcg,thread=multi \
-m 4096 \
-smp 6 \
-cpu cortex-a72 \
-serial stdio \
-device ramfb \
-device qemu-xhci \
-device usb-tablet \
-device usb-kbd \
-drive file=win11.qcow2,if=none,id=NVME1 \
-device nvme,drive=NVME1,serial=nvme-1 \
-drive file=AAVMF_CODE.ms.fd,format=raw,if=pflash,index=0,readonly=on \
-drive file=AAVMF_VARS.ms.fd,format=raw,if=pflash,index=1 \
-drive readonly=on,media=cdrom,if=none,id=cdrom -device usb-storage,drive=cdrom \
-net nic,model=virtio \
-net user \
"$@"
NOTE for Windows 11 24H2, you might need to use -cpu cortex-a710
(in a version of qemu new enough to support it)
-m
is the amount of memory in MB, and -smp
is the number of cores to provide the VM. For KVM, remove ,virtualization=true
from -M
(nested virtualization isn't supported for aarch64), change -accel
to kvm
, and change -cpu
to max
.
On the first boot, you are going to need to hit Esc at the firmware loading screen to get into the configuration UI. In there, go to Device Manager
, Secure Boot Configuration
, and uncheck Attempt Secure Boot
. Then Esc out, go to OVMF Platform Configuration
, and change the preferred resolution to 1024x768
. Commit changes and exit
, Esc back to the main menu, and Reset
. Hit Esc again to get back into the UI. Go to Boot Manager
, and select the UEFI QEMU NVMe Ctrl nvme-1 1
option to boot the Windows image. As part of its setup, it will add a Windows Boot Manager
boot entry to the top of the list, so you don't have to worry about changing the boot order right now.