Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

1958llakin

macrumors newbie
Original poster
Nov 18, 2020
6
43

I was able to successfully virtualize Windows 10 for ARM on M1 with Alexander Graf's QEMU hypervisor patch.​


Screenshot:

qemu-windows-10.png


How to virtualize Windows 10 on M1:

1. 
Download qemu-m1.zip from https://mega.nz/file/QYB0QTrC#p6IMBJlFqqNKuGonwrDkPOVKQj8yHCVgiLOYVaGvs4M or this forum attachment. It contains pre-built versions of qemu-system-aarch64, efi-virtio.rom, and QEMU_EFI.fd. (All of these are open-source, and you can build them yourself by following instructions in the next section.)
2. Double click qemu-m1.zip to unzip it.
3. Download Windows Insider Preview ARM64 from Microsoft at https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewARM64, which will get you a VHDX image.
4. Using Finder, move the downloaded VHDX image into the unzipped qemu-m1 folder.
5. Open Terminal and navigate to the qemu-m1 folder. Copy and paste the code below to Terminal, and press return.
Code:
cd ~/Downloads/qemu-m1
6. Start the QEMU virtual machine. Copy and paste the code below to Terminal (copy and paste the entire block all at once), and press return.
Code:
DYLD_LIBRARY_PATH=. \
./qemu-system-aarch64 \
-M virt \
-accel hvf \
-m 5G \
-smp 4 \
-cpu max \
-device ramfb \
-serial stdio \
-drive file=Windows10_InsiderPreview_Client_ARM64_en-us_20231.VHDX,if=none,id=NVME1 \
-device nvme,drive=NVME1,serial=nvme-1 \
-device nec-usb-xhci \
-device usb-kbd \
-device usb-tablet \
-device intel-hda -device hda-duplex \
-drive file=vars-template-pflash.raw,if=pflash,index=1 \
-bios QEMU_EFI.fd
7. Set up Windows 10 and enjoy!

How to increase resolution to 1024x768:​

1. Shut down Windows.
2. qemu-system-aarch64 > Quit QEMU > Quit.
3. Start the virtual machine with the same command line argument as listed in step 6 of the previous section.
4. When QEMU shows "Start boot option", press the escape key on your keyboard.
5. Use the arrow down key to move selection to "Device Manager", press return, then move down to "OVMF Platform Configuration", and press return. Changing selection may take a while to update after pressing the arrow key. It is normal.
6. Highlight <640x480> or <800x600> next to "Change Preferred", press the return key, and change selection to 1024x768.
7. Press both fn and F10 on your keyboard to save the changes. (If you're using a PC keyboard, just press F10).
8. Press esc to go back to the main menu.
9. Press down arrow a few times to move selection to "Continue", then press return on your keyboard.
10. After Windows has booted, shut down Windows.
11. qemu-system-aarch64 > Quit QEMU > Quit.
12. Start the virtual machine with the same command line argument as listed in step 6 of the previous section.

How to get internet access in the virtual machine:​

1. Download the virtio driver ISO from https://fedorapeople.org/groups/vir...o/virtio-win-0.1.190-1/virtio-win-0.1.190.iso
2. Move the downloaded ISO to the qemu-m1 folder.
3. In Windows 10, right click on the Start menu, then choose “Command Prompt (Admin)”.
4. Click “Yes” in the UAC prompt.
5. Allow drivers that are test-signed.
Code:
bcdedit -set TESTSIGNING ON
6. Shut down Windows.
7. qemu-system-aarch64 > Quit QEMU > Quit.
8. Boot QEMU again with updated arguments.
Code:
DYLD_LIBRARY_PATH=. \
./qemu-system-aarch64 \
-M virt \
-accel hvf \
-m 5G \
-smp 4 \
-cpu max \
-device ramfb \
-serial stdio \
-drive file=Windows10_InsiderPreview_Client_ARM64_en-us_20231.VHDX,if=none,id=NVME1 \
-device nvme,drive=NVME1,serial=nvme-1 \
-device nec-usb-xhci \
-device usb-kbd \
-device usb-tablet \
-device intel-hda -device hda-duplex \
-drive file=vars-template-pflash.raw,if=pflash,index=1 \
-drive file=virtio-win-0.1.190.iso,media=cdrom,if=none,id=cdrom -device usb-storage,drive=cdrom \
-net nic,model=virtio \
-net user \
-bios QEMU_EFI.fd
9. After Windows boots, right click on the Start menu, and choose “Device Manager”.
10. In the “Other devices” section, scroll all the way to the end.
11. Right click on the last “Unknown device” > Update drivers > Browse my computer for drivers > Browse.
12. Choose the virtual CD Drive (D:) virtio-win > OK > Next > Allow.
13. You should now have internet in the Windows 10 virtual machine.

Tips:​

If you're getting any GateKeeper warnings, remove the Quarantine extended attribute (preferred) or temporarily turn off GateKeeper (not recommended):
Code:
xattr -rd com.apple.quarantine ~/Downloads/qemu-m1

How to build and run QEMU on M1 from source:​

This section is for advanced users who are comfortable using Terminal.
1. If you already installed Homebrew or required dependencies using Rosetta 2, follow https://github.com/homebrew/install#uninstall-homebrew to uninstall the Intel version of Homebrew and other dependencies.
2. Install the native arm64 version of Homebrew on Apple Silicon. Follow https://soffes.blog/homebrew-on-apple-silicon, and look for the “Multiple Homebrews” section, then add /opt/homebrew/bin to your path.
3. Download the python3.9 Homebrew formula from https://github.com/Homebrew/homebrew-core/raw/master/Formula/python@3.9.rb. Open it in any text editor, then edit line 124 into the following, and save the edited Ruby file.
Code:
args << "MACOSX_DEPLOYMENT_TARGET=11.0"
4. Install python3.9.
Code:
brew install ~/Downloads/python@3.9.rb
5. Install other required dependencies.
Code:
brew install pkg-config glib pixman ninja
6. Download Alexander Graf's QEMU hypervisor patch at https://patchwork.kernel.org/series/391797/mbox/
6. Checkout QEMU, then cd into it.
Code:
git clone https://git.qemu.org/git/qemu.git
cd qemu
7. Apply Alexander's patch.
Code:
git apply ~/Downloads/hvf-Implement-Apple-Silicon-Support.patch
8. Open ~/qemu/target/qrm/hvf/hvf.c in any text editor, and change the hvf_arch_init_vcpu method into:
Code:
int hvf_arch_init_vcpu(CPUState *cpu)
{
    ARMCPU *arm_cpu = ARM_CPU(cpu);
    CPUARMState *env = &arm_cpu->env;

    env->aarch64 = 1;

    hv_return_t ret;
    ret = hv_vcpu_set_sys_reg(cpu->hvf_fd, HV_SYS_REG_SCTLR_EL1,
                              arm_cpu->reset_sctlr);

    return ret;
}
8. Configure the build.
Code:
./configure --cpu=aarch64 --target-list=aarch64-softmmu
9. Build QEMU.
Code:
make
10. When QEMU is built, cd into the build directory.
Code:
cd build
11. Download EDK2 from https://www.kraxel.org/repos/jenkins/edk2/edk2.git-aarch64-0-20201023.1506.gf69a2b9a42.noarch.rpm
12. Extract EDK2.
Code:
tar -xf ~/Downloads/edk2.git-aarch64-0-20201023.1506.gf69a2b9a42.noarch.rpm
13. Move QEMU_EFI.fd to the build folder.
Code:
mv ./usr/share/edk2.git/aarch64/* ./
14. Run the QEMU virtual machine.
Code:
./qemu-system-aarch64 \
-M virt \
-accel hvf \
-m 5G \
-smp 4 \
-cpu max \
-device ramfb \
-serial stdio \
-drive file=Windows10_InsiderPreview_Client_ARM64_en-us_20231.VHDX,if=none,id=NVME1 \
-device nvme,drive=NVME1,serial=nvme-1 \
-device nec-usb-xhci \
-device usb-kbd \
-device usb-tablet \
-device intel-hda -device hda-duplex \
-drive file=vars-template-pflash.raw,if=pflash,index=1 \
-bios QEMU_EFI.fd
15. Set up Windows 10 and enjoy!

Source:
https://patchwork.kernel.org/project/qemu-devel/list/?series=391797
 

Attachments

  • qemu-m1.zip
    7.7 MB · Views: 1,477
Last edited:
I don't know if it's just my setup, but even with the pre-compiled binary package, I still needed pixman and glib (ninja and pkg-config seem to be dependencies for those 2 already) specifically in my /opt/brew/ install.

Also, not sure if I really needed to set brew up as native arm64, but that's what I did anyways it seems brew needs to have been set up with arm64 (aarch64) as well. Only roadblock was getting python@3.9 to install properly, since there's currently one small issue with the formula. After that, it's smooth sailing and I'm up and running.

Thanks for the very detailed instructions!
 
  • Like
Reactions: 1958llakin
If someone puts that all together as a one click Virtual PC style app then I’ll look into it.
This is far from "stable", even missing critical features
nop is not implemented, therefore a CPU core assigned to VM will always takes up 100% utilization, even the VM is in standby.
Power control is not finished, you cannot power off or restart VM without restart the hypervisor(application that runs the vm).
Virtual Display is now merely a simple frame-buffer device, which does not support 3D acceleration(like parallel), it even has only very limited resolution support(up to 1024x768 now)

It is somehow pointless to make a "one-click" version at this stage, no one wants to use it in production.
 
I don't know if it's just my setup, but even with the pre-compiled binary package, I still needed pixman and glib (ninja and pkg-config seem to be dependencies for those 2 already) specifically in my /opt/brew/ install.

Also, not sure if I really needed to set brew up as native arm64, but that's what I did anyways it seems brew needs to have been set up with arm64 (aarch64) as well. Only roadblock was getting python@3.9 to install properly, since there's currently one small issue with the formula. After that, it's smooth sailing and I'm up and running.

Thanks for the very detailed instructions!
Ha, I missed the dependency. Fixed the pre-compiled binary package and Terminal command.
 
  • Like
Reactions: bill-p
Yeah, to report back, Shenzhen I/O launches and works without a hitch for me, so x86 (32-bit) emulation works! And hell, even with just 2 cores, it runs slightly faster than how I remember the Surface Pro X does it.

cxBcpOO.png


^ 2 cores seems enough for this and many other things.

Also, I was able to get Ubuntu Mate working with the other 2 cores. Heck, it runs faster than my overclocked Raspberry Pi 4 even.

This is actually much more useful than people realize. Once we have nop implemented, then I won't have any problem giving more CPUs to these VMs.
 
That is awesome! I don't have an M1 Macbook to test on... can someone do a test as to what the overhead impact is on this setup vs a normal Macbook with the same VM?
 
There is no hardware accelerated driver for Windows 10 on ARM as a guest machine yet because... I'm guessing Microsoft didn't really expect to optimize performance of Win10ARM in VM.

Also, it's hard to compare this against a regular x86 Windows 10 machine because there is barely anything running on Windows 10 ARM to compare. But the experience in general is close to virtualbox running full x86 Windows 10 on an Intel Core i9. That makes sense because VirtualBox also doesn't support the same level of hardware acceleration as Parallels and VMWare.

If you're running Linux, though, we have much better luck:
dDMqweM.png


This blows my Pi 4 way out of the water. It may in fact be the fastest ARM64 version of Ubuntu that I have ever tried. Even nVidia's ARM boards pale in comparison. We have OpenGL ES 3.1 support, so desktop compositor and most of the eye candies just "work".
 
There is no hardware accelerated driver for Windows 10 on ARM as a guest machine yet because... I'm guessing Microsoft didn't really expect to optimize performance of Win10ARM in VM.

Also, it's hard to compare this against a regular x86 Windows 10 machine because there is barely anything running on Windows 10 ARM to compare. But the experience in general is close to virtualbox running full x86 Windows 10 on an Intel Core i9. That makes sense because VirtualBox also doesn't support the same level of hardware acceleration as Parallels and VMWare.

If you're running Linux, though, we have much better luck:
dDMqweM.png


This blows my Pi 4 way out of the water. It may in fact be the fastest ARM64 version of Ubuntu that I have ever tried. Even nVidia's ARM boards pale in comparison. We have OpenGL ES 3.1 support, so desktop compositor and most of the eye candies just "work".
We still don't have hardware acceleration under linux as well. The Linux native paravirutal virgl is only available on Linux hosts for now, and the GL ES stuff is rendered by CPU. Playingback 4K without issue is just because M1 is good enough to do that.
 
Last edited:
  • Wow
Reactions: Madd the Sane
EDIT: oops...wasted an hour and duplicated work. 1958llakin had already updated his attachment with included libraries. my build is unnecessary :)
 
Last edited:
  • Like
Reactions: jdb8167 and bill-p
We still don't have hardware acceleration under linux as well. The Linux native paravirutal virgl is only available on Linux hosts for now, and the GL ES stuff is rendered by CPU. Playingback 4K without issue is just because M1 is good enough to do that.

Ah, yeah, you're right.

I've just dropped down to 1 CPU core in the VM (system can now last 10 hours), and just with the 1 core, the most it can do is 1440p60 with some dropped frames. 1080p60 is perfectly fine even in fullscreen, though.

In any case, I think I've gotten the configuration "right" this time. 4GB, 1 core. Battery lasts a long time (10 hours) and I can leave the VM running indefinitely in the background. It is fast, responsive, and very usable. Actually, at this point, I think I can use this for some serious stuffs until Parallels and VMWare are ready.

This actually works far too well. I'm amazed:

hfvGDm9.png


I may fiddle with xrandr a bit more to get 1280 x 800, but I think this is a good stopping point. Sound also works and it's more seamless than it looks.
 
Last edited:
Yeah, to report back, Shenzhen I/O launches and works without a hitch for me, so x86 (32-bit) emulation works! And hell, even with just 2 cores, it runs slightly faster than how I remember the Surface Pro X does it.

cxBcpOO.png


^ 2 cores seems enough for this and many other things.

Also, I was able to get Ubuntu Mate working with the other 2 cores. Heck, it runs faster than my overclocked Raspberry Pi 4 even.

This is actually much more useful than people realize. Once we have nop implemented, then I won't have any problem giving more CPUs to these VMs.

anybody tried to get the Hybrid version of Microsoft office for windows arm to work in that windows arm VM? If so how well does it work?
 
Is nested Virtualization working - or can you run WSL2 under virtualized Windows?
 
Is nested Virtualization working - or can you run WSL2 under virtualized Windows?

Just a note: the Store isn't working in VM. You'll have to manually set up everything yourself through PowerShell.

Seeing as you can just very easily make a separate Linux VM with your favorite distro and go to town with it, I don't see why WSL2 would be useful at all...
 
Quick note:
You need to manually add
Code:
highmem=off
to the startup script after v2 patch,line four is now:
Code:
-M virt,highmem=off \

By the way: for some reason my previous installation of windows stopped booting, replacing disk now.
 
Quick note:
You need to manually add
Code:
highmem=off
to the startup script after v2 patch,line four is now:
Code:
-M virt,highmem=off \

By the way: for some reason my previous installation of windows stopped booting, replacing disk now.

Awesome, can you post the new precompiled patch?
 
Not sure if it will work on your computers, I just replaced qemu-system-aarch64 with mine in the zip, did you static link any libraries?

Please note: You may have to start from a new Windows VHDX after this update, the one that used by the old version may not boot.

Edit: Updated and relinked most libs, now it should work on your computer as long as lib files are in the same directory of the executable.
 

Attachments

  • qemu-m1 v2.zip
    8.7 MB · Views: 484
Last edited:
Is nested Virtualization working - or can you run WSL2 under virtualized Windows?
No, WSL2 does not boot, nested virtualization is not working yet.
But WSL1 does work, though I don't know why you want some setup like this, too weird🤣:
Screen Shot 2020-11-30 at 01.05.07.png
 
Just a note: the Store isn't working in VM. You'll have to manually set up everything yourself through PowerShell.

Seeing as you can just very easily make a separate Linux VM with your favorite distro and go to town with it, I don't see why WSL2 would be useful at all...

Depends on your workflow i guess. Currently i am using WSL extensions for Visual Studio Code.
 
Just out of curiosity, can someone run the ARM64 version and the x86 version of Geekbench within Windows and post the numbers?
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.