Tag Archives: Arm

Windows 10 for ARM with QEMU for Windows

In the previous post I described the steps of emulating an ARM64/aarch64 system with QEMU in order to boot the ARM version of Ubuntu 22.04.

I also wanted to try Windows for ARM so that I can examine how I can build software for it.

While it is not that widespread yet, with recent developments regarding the ARM platform (ARM based Apple devices, Qualcomm attacking the PC market) it is clearly a platform that is worth exploring.

Fortunately with QEMU we can create a virtual environment that Windows for ARM is willing to run on.

I picked Windows 10 over Windows 11 for the following reasons:

  • I hoped there would be more experience with it already, and more documentation, which would increase my chances for success
  • Older OS usually means less HW requirements, which is quite helpful with performance when emulating another system
  • While supporting only the latest and greatest version of an OS has it’s advantages it does mean less users

I read the following posts before and during my attempt:

Unfortunately none of them were sufficient enough for me to be successful.

That’s why I decided to write up this post describing my experience, and providing a step by step guide.

Do note that this guide is for Windows.

Preparation

  • Create a working directory for your Windows for ARM environment. I my case it’s L:\projects\win10arm
  • Download QEMU_EFI.img and QEMU_VARS.img files from here, and copy them to your working directory.

The UEFI BIOS found on that link was modified and compiled by Rafael Rivera.
The modifications include re-enabled VGA virtual display support, and a modified Windows loading screen logo.

Create a virtual harddrive

  • Right click the start menu and click Disk Manager
  • Click Actions and then Create VHD
  • Set up parameters as such: 60 GB size, VHDX, Fixed size and then click OK.
  • Right click on the new disk (Disk 3 on my picture) and select Initialize Disk
  • Select GPT and then click OK.
  • When it finished right click again, and now select detach VHD.

Note: Fixed size is important, because otherwise the emulated environment will only see the initial size which is just a few MBs.

The QEMU startup batch file

  • Create a new batch file in your working directory with the name start.bat and the following contents:
@echo off
L:\qemu\qemu-system-aarch64.exe ^
-M virt,virtualization=true ^
-accel tcg,thread=multi ^
-cpu cortex-a57 ^
-smp 4 ^
-m 4G ^
-pflash QEMU_EFI.img -pflash QEMU_VARS.img ^
-device VGA ^
-device nec-usb-xhci ^
-device usb-kbd ^
-device usb-mouse ^
-nic user,model=virtio ^
-device virtio-blk,drive=system ^
-drive if=none,id=system,format=raw,file=.\sys.vhdx ^
-device usb-storage,drive=drivers ^
-drive if=none,id=drivers,readonly=on,format=raw,media=cdrom,file=.\virtio-win-0.1.240.iso ^
-device usb-storage,drive=install ^
-drive if=none,id=install,format=raw,media=cdrom,file=.\win10arm.iso

Obviously you should change the paths to your own.

Let’s see what these parameters mean:

  • -M virt,virtualization=true We’re starting a generic virtual machine which means it’s not an emulation of any real hardware, with “Arm Virtualization Extensions” enabled.
  • -accel tcg,thread=multi Use one host CPU thread / emulated guest thread
  • -cpu cortex-a57 We’re emulating a cortex-a57 CPU
  • -smp 4 Use 4 virtual CPUs
  • -m 4G Use 4 GB of RAM
  • -pflash QEMU_EFI.img Use the BIOS code in QEMU_EFI.img
  • -pflash QEMU_VARS.img Use QEMU_VARS.img to store the UEFI BIOS settings
  • -device VGA Use a virtual VGA device for output
  • -device nec-usb-xhci Use a virtual USB controller
  • -device usb-kbd Virtual USB keyboard
  • -device usb-mouse Virtual USB mouse
  • -nic user,model=virtio Use a user mode virtual network interface
  • -device virtio-blk,drive=system -drive if=none,id=system,format=raw,file=.\sys.vhdx This is the system drive where Windows will be installed to and run from
  • -device usb-storage,drive=drivers -drive if=none,id=drivers,readonly=on,format=raw,media=cdrom,file=.\virtio-win-0.1.240.iso This is the virtio driver CD-ROM
  • -device usb-storage,drive=install -drive if=none,id=install,format=raw,media=cdrom,file=.\win10arm.iso This is the Windows 10 for ARM installer DVD

Note: The virtualization extension is an absolute must. Without it I couldn’t even boot the installer, and took me a while to find the reason.

Installation

The installation itself is the same as it would be on an x86 system (select options, next, next), so I will focus on the differences.

Also do note that even the installation is going to be quite slow. It can take hours.

You can start the emulated system with start.bat

After starting up, the machine will try to boot and fail, so it will ask you to tell it the device it should boot from. It presents you the UEFI shell where you should type ‘exit’ which will make it enter the character based GUI. There you must select the Boot Manager menu item, then select the boot device. In my case it was the one you see on the screenshot: an UEFI QEMU USB HARDDRIVE which is actually the Windows 10 for ARM installation DVD.

On the “Where do you want to install Windows” screen you will see no hard drives at first, because the Windows installer doesn’t have drivers for the virtualized hard drive. You can fix this by installing the virtio driver you downloaded earlier.

  • Click Load driver
  • Select the virtio-win CD drive
  • Select the viostor/w10/ARM64 directory and click OK
  • The installer will show you that it found the Red Hat Virtio SCSI controller driver. Click next
  • The installer will install this driver and then the virtual hard drive will finally show up

Sometimes the installer will show you yellow error messages like “OOBKEYBOARD”. You can safely click on the skip button.

You need to skip the Internet setup because the Installer doesn’t have drivers for the virtual network adapter. It will have to be set up after installation.

After the install process finishes you will get a familiar Windows 10 desktop, it’s just running in an emulated ARM64 environment

Post install

Performance improvements

  • Turn off / postpone updates
  • Open Task Manager and end the Microsoft OneDrive setup
  • On the startup tab of Task Manager disable Microsoft OneDrive Setup
  • Turn off Microsoft Compatibility Telemetry with the following commands:
sc stop "DiagTrack"
sc config "DiagTrack" start=disabled
  • Turn off Printer Spooler with the following commands:
sc stop "Spooler"
sc config "Spooler" start=disabled
  • Turn off search indexing with the following commands:
sc stop "WSearch"
sc config "WSearch" start=disabled

Installing the network driver

  • Go to Device Manager through Control Panel (it doesn’t open from the start menu directly for some reason).
  • Click on Ethernet Controller in the Other devices category
  • Right click, and click on properties
  • Click on Update Driver
  • click on Browse my computer for drivers
  • Click browse and select the virtio-win CD-ROM and select the NetKVM\w10\ARM64 folder
  • Click next

Changing display resolution

  • Enter the UEFI BIOS menu
  • Go to Device Manager -> OVMF Platform Configuration
  • Change the resolution in the Change Preferred option
  • Select Commit Changes and Exit, then hit enter
  • Reboot