When following this guide on a host not capable of native arm64 KVM, replace -M virt -cpu host -accel kvm
with -M virt,virtualization=on -cpu max
.
The reason for virtualization=on
is that the Windows bootloader does an smc #0
PSCI call, but without EL2, QEMU's TCG does not handle those because PSCI is in HVC mode and such that instruction is treated as undefined. With KVM enabled, smc #0
is handled properly.
Workaround in QEMU for using TCG without virtualization=on
:
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index b871350856..de11ff51d1 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2056,7 +2056,7 @@ static void machvirt_init(MachineState *machine)
*/
if (vms->secure && firmware_loaded) {
vms->psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
- } else if (vms->virt) {
+ } else if (1 || vms->virt) {
vms->psci_conduit = QEMU_PSCI_CONDUIT_SMC;
} else {
vms->psci_conduit = QEMU_PSCI_CONDUIT_HVC;
- Download the VM disk image from https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewarm64 and the latest virtio-win.iso from https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/. Build 22589 is known to work, while build 25226 is known not to work (unhandled exception during boot).
- Perform the initial boot. For some reason performance is abysmal with the GTK UI, so use VNC:
qemu-system-aarch64 -M virt -cpu host -accel kvm -m 2G -smp 2 -device ramfb -bios /usr/share/qemu/qemu-uefi-aarch64.bin -device qemu-xhci -device usb-kbd -device usb-tablet -drive file=Windows11_InsiderPreview_Client_ARM64_en-us_22598.VHDX,format=vhdx,if=none,id=boot -device usb-storage,drive=boot,serial=boot -drive file=virtio-win.iso,media=cdrom,if=none,id=iso -device usb-storage,drive=iso -nic user,model=virtio-net-pci,mac=52:54:98:76:54:32 -vnc :0
. On some earlier QEMU/kernel (?) versions,ramfb
has some issues with invalidation (?) causing artifacts, you'll have to ignore them untilvirtio-gpu
can be used. At least since build 25931, it's necessary to provide a network connection to finish the initial setup. The default QEMU MAC address will result in a false UUID match with some AutoPilot enrolled devices, forcing an "Intellek" domain login. To avoid that, use a different MAC address, e.g.52:54:98:76:54:32
from the QEMU man page. To have a higher resolution with ramfb, enter the OVMF setup by pressing F10 during boot, change the preferred resolution to 1024x768 and reset. - This might take a while. If it appears stuck at "Getting ready" for 10min (give it a bit more time without KVM) or you get a BSOD (watchdog timeout), reset. If you get an error message "Windows installation cannot proceed", press Shift-F10 to open a cmd, run
regedit
and setHKEY_LOCAL_MACHINE\SYSTEM\Setup\Status\ChildCompletion\Setup
to 3 and click onOk
to reboot. - When it asks for the initial setup (country, keyboard layout) press Shift-F10 to open a cmd, or (if it does not work) Ctrl-Shift-Esc to open the task manager and launch cmd with admin privs.
- Run
bcdedit /set TESTSIGNING ON
to allow loading some drivers during boot. While virtio drivers are signed, they don't work without this for some reason. - Start explorer.exe, navigate to the virtio drivers in D: and install NetKVM, viogpudo, viostor and vioscsi by right clicking on the
.inf
file within thew11/ARM64
folders and selecting "Install". If it complains about driver signatures, navigate to thecert
folder and install the certificate into the devicesTrusted Publishers
store. - Complete the setup as usual. To avoid using a Microsoft account, attempt to sign in as "Administrator" with some random string as password, then click "Next" on the "Oops, something went wrong" screen. If that no longer works, the
oobe \bypassnro
method is necessary. - Shut down Windows.
- Now virtio devices can be used:
qemu-system-aarch64 -M virt -cpu host -accel kvm -m 4G -smp 4 -device virtio-gpu-pci -bios /usr/share/qemu/qemu-uefi-aarch64.bin -device qemu-xhci -device usb-kbd -device usb-tablet -drive file=Windows11_InsiderPreview_Client_ARM64_en-us_22598.VHDX,format=vhdx,if=none,id=boot -device virtio-scsi -device scsi-hd,drive=boot -nic user,model=virtio-net-pci,mac=52:54:98:76:54:32 -vnc :0
. The first boot will take a while with a disabled display, be patient. If it does not work, try to boot with the previous QEMU command but also add-device virtio-gpu-pci
and some virtio-scsi HD, to make sure the driver is properly selected.
Assuming the VM's hard drive has Windows and the
virtio-gpu
driver correctly installed, is it possible to boot withoutramfb
?