Since the development stages of Windows 10, Microsoft has been releasing a version of Windows that runs on 64-bit ARM (AArch64) based CPUs. Despite some hardware shipping with Windows 10 ARM 1 2 3 this port has received little attention and you can barely find programs that run on it.
Naturally, I wanted to try this out to see if it worked. And it turned out it does!
Getting the ISO
I'm not aware of any Microsoft page that lets you download an ARM64 ISO, so this part relies on community-made solutions instead.
I looked for the right ESD download link and used an ESD>ISO conversion script to get a bootable ISO (both found on the MDL forums).
Alternatively adguard's download page provides similar scripts that download and pack an ISO for you. However, in my experience these take a long time (hours) to finish.
I had no success booting version 2004 or 20H2 (specifically: 19041.388 / 19041.423) so I went with version 1909 (18363.592) instead.
Before we begin we also need:
an appropriately sized disk image (
qemu-img create -f qcow2 disk.qcow2 64G)
QEMU_EFI.fdextracted from the
edk2.git-aarch64RPM found here
The qemu command line then looks as follows:
isoname=18363.592.200109-2016.19H2_RELEASE_SVC_REFRESH_CLIENTBUSINESS_VOL_A64FRE_DE-DE.ISO virtio=~/Downloads/virtio-win-0.1.185.iso qemu-system-aarch64 -M virt -cpu cortex-a53 -smp 4 -m 4096 \ -device qemu-xhci -device usb-kbd -device usb-tablet \ -drive file=disk.qcow2,if=virtio \ -nic user,model=virtio \ -drive file="$isoname",media=cdrom,if=none,id=cdrom -device usb-storage,drive=cdrom \ -drive file="$virtio",media=cdrom,if=none,id=drivers -device usb-storage,drive=drivers \ -bios QEMU_EFI.fd -device ramfb
You can then follow the installation process as normal. Before partitioning
the disks the setup will ask you to load disk drivers, these can be found at
viostor/w10/ARM64 on the virtio cdrom.
Qemu video output
The above command line already takes these limitations into account, these sections are for explanation only.
A previous blogpost on running Windows 10 ARM in QEMU has used a patched EDK2 to get support for standard VGA back in. It's not clear to me why EDK2 removed support if it was working, but this is not a solution I wanted to use either way.
It turns out 4 that the options on ARM are limited to virtio gpu and ramfb. Virtio graphics are Linux-only so that leaves ramfb.
Attaching disks with Qemu
virt machine has no SATA controller we cannot attach a hard disk
to the VM the usual way, I went with virtio here instead.
It would have been possible to do this over
usb-storage, this works out of the box
and would have saved us all the work with virtio drivers (except for networking 5).
If you do, EDK2 will boot the Windows CD fine but setup will ask you to load drivers early (because it cannot find its own CD). None of the virtio drivers can fix this situation, leaving you stuck with no clear indication what went wrong.
The onboarding process has a few hiccups (in particular device detection), if you retry it a few times it'll let you continue anyway.
High CPU Usage
After the first boot I noticed two
regsvr32.exe processes at 100% CPU that
didn't seem to finish in reasonable time.
Further investigation with Process Explorer 6 showed these belonging to Windows' printing service. Since I don't want to print in this VM anyway, the affected service can just be stopped and disabled:
We're still missing the network driver from the virtio cdrom. Unfortunately the NetKVM driver doesn't seem to be properly signed, so you have to enable loading unsigned drivers first (and reboot!):
bcdedit /set testsigning on
Afterwards the right driver can be installed from the device manager (
NetKVM/w10/ARM64 on cdrom).
General Performance Tweaks
These aren't specific to Windows 10 ARM or Virtual Machines, but are most useful in that case.
REM Disable Windows Search Indexing sc stop "WSearch" sc config "WSearch" start= disabled REM Disable Automatic Defragmentation schtasks /Delete /TN "\Microsoft\Windows\Defrag\ScheduledDefrag" /F REM Disable Pagefile wmic computersystem set AutomaticManagedPagefile=FALSE wmic pagefileset delete REM Disable Hibernation powercfg -h off
Higher Display Resolution
As of writing QEMU's ramfb has its resolution locked to 800x600, which even breaks EDK2's menu (press F2 or Esc during boot).
vars-template-pflash.rawfrom the same edk package as earlier (UEFI will store its settings in there).
The display resolution can then be set up to 1024x768 under Device Manager > OVMF Platform Configuration.
With a bit of preparation it is possible to run Windows 10 ARM in a virtual machine. Although the emulation is pretty slow you could feasibly use this to test one or two programs.
If you have ARM64 hardware with sufficient specs and KVM support, the
-enable-kvm flag can get you native execution speed, though I haven't had
a chance to see how this performs yet.
usb-netdevice does not function and doesn't appear in Windows' device manager at all.
Procexp for ARM64 is available here: http://live.sysinternals.com/ARM64/