Run Windows 10 on ARM64 in QEMU on Apple Silicon Mac
Tags: apple, mac, windows10, qemu
Published: 2020-12-27 00:23:51

## Running Windows 10 on ARM

1. Install Xcode from App Store or install Command Line Tools on your Mac running on Apple Silicon.

    ```
    xcode-select --install
    ```

2. Install MacPorts and QEMU dependencies.

    https://www.macports.org/install.php

    ```
    sudo port install ninja pkgconfig glib2 libpixman
    ```

3. Clone QEMU source code.

    ```
    git clone https://git.qemu.org/git/qemu.git
    ```

4. Create a local branch then apply Hypervisor.framework patches that @[_AlexGraf](https://twitter.com/_AlexGraf) made.

    ```
    cd qemu
    git checkout master -b wip/hvf
    curl 'https://patchwork.kernel.org/series/400619/mbox/'|git am
    ```

5. Build QEMU

    Before building, **please ensure there are no x86_64 tools enabled**, such the one installed by Homebrew, by rewriting `PATH` or `PKG_CONFIG_PATH`.

    ```
    mkdir build
    cd build
    ../configure --target-list=aarch64-softmmu --enable-cocoa
    make -j
    ```

6. Download pre-build EDK II OVMF EFI image for QEMU.

    This EFI image is built from `stable202011` tag with additional resolutions in `QemuRamfb.c`.

    https://gist.github.com/niw/4f1f9bb572f40d406866f23b3127919b/raw/f546faea68f4149c06cca88fa67ace07a3758268/QEMU_EFI-cb438b9-edk2-stable202011-with-extra-resolutions.tar.gz

    To build it from the source code for adding more resolutions, see the following section.

7. Prepare pflash for non-volatile variable store, such as screen resolution.

    In the directory where you downloaded `QEMU_EFI-....tar.gz`, run following commands.

    ```
    cd ~/Downloads
    tar xzvf QEMU_EFI-*.tar.gz
    dd if=/dev/zero of=pflash0.img bs=1m count=64
    dd if=/dev/zero of=pflash1.img bs=1m count=64
    dd if=QEMU_EFI.fd of=pflash0.img conv=notrunc
    dd if=QEMU_VARS.fd of=pflash1.img conv=notrunc
    ```

    - This step is optional, you can use `-bios ~/Downloads/QEMU_EFI.fd` instead of `-drive ...if=pflash` lines in the next step,
      but in that case, any changes in EFI will not be persistent.

8. Download Windows 10 on ARM Insider Preview

    https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewARM64

9. Convert VHDX downloaded Windows image to qcow2 format

    It seems that VHDX often gets broken while it is being used, so probably it is better to convert it to qcow2 format before using it.

    ```
    qemu-img convert -p -O qcow2 ~/Downloads/Windows10_InsiderPreview_Client_ARM64_en-us_20231.VHDX ~/Downloads/Windows10_InsiderPreview_Client_ARM64_en-us_20231.qcow2
    ```

10. Run Windows 10

    ```
    ./qemu-system-aarch64 \
      -monitor stdio \
      -M virt,highmem=off \
      -accel hvf \
      -cpu cortex-a72 \
      -smp 4 \
      -m 4096 \
      -drive file=~/Downloads/pflash0.img,format=raw,if=pflash,readonly=on \
      -drive file=~/Downloads/pflash1.img,format=raw,if=pflash \
      -device ramfb \
      -device qemu-xhci \
      -device usb-kbd \
      -device usb-tablet \
      -device intel-hda \
      -device hda-duplex \
      -drive file=~/Downloads/Windows10_InsiderPreview_Client_ARM64_en-us_20231.qcow2,format=qcow2,if=none,id=boot,cache=writethrough \
      -device nvme,drive=boot,serial=boot
    ```

    - Please modify each path to the image depends on your environment.
    - Hit `ESC` while you see TianoCore, then `Device Manager`, `OVMF Platform Configuration`, `Change Preferred Resolution for Next Boot` to change screen resolution.
    - To add more resolutions, follow "Build EDK II OVMF EFI image from the source code" below and modify `OvmfPkg/QemuRamfbDxe/QemuRamfb.c` then build new `QEMU_EFI.fd`.
    - Use `-device usb-tablet` instead of `-device usb-mouse` allows transparently moving mouse cursor.
    - `-device intel-hda -device hda-duplex` to enable audio.
    - `-nic user,model=virtio` is the network interface. To enable it, see the following section.

## Enable the internet

VirtIO NIC is not enabled by default. To make it works, you need to 

device driver.

1. Download VirtIO device drivers ISO from [Fedora Project](https://docs.fedoraproject.org/en-US/quick-docs/creating-windows-virtual-machines-using-virtio-drivers/index.html#virtio-win-direct-downloads).

    https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.190-1/virtio-win-0.1.190.iso

2. Mount device drivers ISO

    Add next options to `qemu-system-aarch64`.

    ```
    -drive file=~/Downloads/virtio-win-0.1.190.iso,media=cdrom,if=none,id=drivers \
    -device usb-storage,drive=drivers
    ```

    Please modify each path to the image depends on your environment.

3. Disable device driver signature enforcement

    Boot Windows, then right click Windows Start button, then select Command Prompt (Admin).

    Use bcdedit to enable test-signed device drivers.

    ```
    bcdedit.exe -set TESTSIGNING ON
    ```

    Then reboot Windows.

    See [here](https://docs.microsoft.com/en-us/windows-hardware/drivers/install/the-testsigning-boot-configuration-option) for the details.

4. Install driver

    Once Windows booted again, then right click Windows Start button, then select Device Manager.

    In Device Manager, select View menu then Devices by Connection.

    Navigate in the device tree, select `ACPU ARM64-based PC`, `Microsoft ACPI-Compliant System`, `PCI Express Root Complex`, then you will see one `Unknown device` there.
    (There are many `Unknown device` in tree but the one under `PCI Express Root Complex` is the VirtIO NIC.)

    Right click `Unknown device` then select Update Drivers, then Browse my computer for drivers, then select `D:\NetKVM\w10\ARM64`.

    Click Next to install `Red Hat VertIO Ethernet Adapter`.


<BR/>
Credits: https://gist.github.com/niw