With the help of Davide Cavalca in the Fedora Asahi Matrix room I was able to get Windows 11 IoT to work. But the instructions were a bit bare bones, so I made a more complete tutorial here. In the end you should have a working Windows VM.
Note that this is the IoT variant of Windows 11, not the full version. The full version probably needs some hacks to get past the minimum requirements Windows has. I prefer to avoid bloat so I use the IoT version.
Here are the steps:
- Create a new directory (I’m using
windows
) for the files we’ll be using. - Download a Windows ISO: Please select your Windows 11 IoT Enterprise LTSC download (pick the ARM64 one).
Rename this file towindows-11-iot.iso
. - Download the virtio-win ISO: Driver installation · virtio-win/kvm-guest-drivers-windows Wiki · GitHub
Rename this file tovirtio-win.iso
. - Create a new virtual disk (you can change the size as you wish, the install described here leaves about 6GB of space after installation):
$ qemu-img create -f qcow2 win11.qcow2 25G
- Create a file
win11.sh
with the following contents, and usechmod +x win11.sh
to make it executable:#!/bin/sh performance_cores=$(awk ' /^processor/ { proc=$3 } /^CPU part/ { if ($4 == "0x023" || $4 == "0x025" || $4 == "0x029" || $4 == "0x033" || $4 == "0x035" || $4 == "0x039") procs=procs ? procs","proc : proc } END { print procs } ' /proc/cpuinfo) taskset -c "$performance_cores" \ qemu-system-aarch64 \ -display sdl,gl=on \ -cpu host \ -M virt \ -enable-kvm \ -m 2G \ -smp 2 \ -bios /usr/share/edk2/aarch64/QEMU_EFI.fd \ -hda win11.qcow2 \ -device qemu-xhci \ -device ramfb \ -device usb-storage,drive=install \ -drive if=none,id=install,format=raw,media=cdrom,file=windows-11-iot.iso \ -device usb-storage,drive=virtio-drivers \ -drive if=none,id=virtio-drivers,format=raw,media=cdrom,file=virtio-win.iso \ -object rng-random,filename=/dev/urandom,id=rng0 \ -device virtio-rng-pci,rng=rng0 \ -audio driver=pipewire,model=virtio \ -device usb-kbd \ -device usb-tablet \ -nic user,model=virtio-net-pci
- Now run
./win11.sh
. A QEMU window pops up. After going through some boot screens, it should show “Press any key to boot from CD or DVD…”. Press any key to boot Windows (quickly, because otherwise you’ll end up in a UEFI console). - Windows should now be booting, and you should end up in the Windows 11 setup. Most of this is straightforward, but there is one thing to be aware of:
- In the “Select location to install Windows 11”, no drives are shown. Fix this by clicking “Load Driver”, “Browse”, expand the virtio-win drive, and select viostor → w11 → ARM64. Click OK. Select the “Red Hat VirtIO SCSI controller” that appears, and click install.
- During the installation, the VM will reboot a few times. Don’t do anything, just let it happen.
- After installation you’ll end up in the first boot wizard (to configure location, keyboard, etc).
- In the “Let’s connect you to a network”, click “Install driver”, open the virtio-win drive, navigate to NetKVM → w11 → ARM64, and click “Select folder”. Wait a few seconds, and the network adapter should appear. You can now continue.
- After completing the installation, you should have a working Windows 11 install!
Shut down the VM as usual to not make Windows scared (don’t just exit the win11.sh
script). To boot it again, simply run the ./win11.sh
script again.
After installation, you can remove the two ISOs and remove the following 4 lines from the win11.sh
script:
-device usb-storage,drive=install \
-drive if=none,id=install,format=raw,media=cdrom,file=windows-11-iot.iso \
-device usb-storage,drive=virtio-drivers \
-drive if=none,id=virtio-drivers,format=raw,media=cdrom,file=virtio-win.iso \
Updates of this tutorial:
- Updated to use SDL screen, which allows for an 800x600 screen that makes installation a whole lot easier, and added instructions how to remove the installation ISOs.
- Updated instructions to add networking.