One subject that comes up very often is the ability to run Windows on an M1-based Mac. Even though many people swear by macOS, Bootcamp and Windows on a Mac still seems to be a widely used option. As these M1-based devices are using a different architecture: ARM, they are not compatible with Mac’s previous and most-used architecture for Windows-based computers: x86. That means that in order to run Windows on an M1 device, you basically have two options: Use an ARM-based version of Windows or emulate an x86-64 based machine and run a regular Windows version. For this article, I will get Windows 11 for ARM running on an M1 MacBook Air by using UTM.
If you are interested, I also created a YouTube video from this blogpost. If you prefer classic text, you can just follow the rest of this article:
As mentioned above, there are two options to get Windows running on an Apple M1-based device. The first involves virtualization, as we can’t (yet) run Windows natively on an M1-based machine. The second involves emulation, where we will translate instructions between the running operating system (Windows in this case) and the hardware. Both methods have their advantages and disadvantages. Emulation offers maximum compatibility as it doesn’t require software written for ARM specifically but it’s pretty slow. Virtualization is fast(er) but requires software written for the hardware platform it is running on.
Both of these methods can be accomplished with UTM (https://github.com/utmapp/UTM). UTM offers QEMU-based virtaluzation and emulation with a handy GUI for both IOS and macOS. As it’s using QEMU under the hood, it is capable of emulating different processor architectures (like x86-64) but it can do virtualization for the same as the host’s architecture as well.
After a quick test, on which I plan to create a more detailed article in the future, using emulation seems to cause a lot of overhead and turns out to be too slow to be usable currently.
Leaving only virtualization as a real option. The downside for this approach is that there is no official way, currently, to get a license for an ARM-based version of Windows. Microsoft decided that this is only available for sale for system builders. Another negative is that there are very little applications compiled for running on an ARM-based Windows version. Fortunately it is possible to run most 32-bit based Windows applications on the ARM-version of Windows, which are available for most applications out there.
For this article, I’ll be using a 2020 M1-based MacBook Air but this should work in the same way for an iMac, Mac Mini, MacBook Pro and even for the recently announced M1 Max and M1 Pro devices.
Getting Windows for ARM on your M1 device
Step 1) Create a Windows 11 for ARM ISO
The first thing we need is installation media for the ARM-based version of Windows 11. If you are part of the Windows Insider program, there is a version available for download, using a VHDX file. Unfortunately, I didn’t manage to get this to work properly and my VM was always stuck during the first boot in a “Getting Started” screen.
Since this didn’t work, I decided to use the UUP Dump method. UUP stands for Unified Update Platform. This is basically a deployment method that Microsoft introduced a few years ago that allows for a sort of incremental updates on parts of Windows, rather than re-deploying everything completely every time. The UUP Dump site allows you to generate a script that will download these UUPs from Microsoft and will combine them in a working ISO file.
To get this all together, first navigate to the website of UUP dump: https://uupdump.net/. Over there, choose the arm64 version of the latest beta channel build:
On the next page, choose the Windows 11 version. At the time of writing this article, this was 10.0.22000.160.
Next, I unchecked “Include updates” but this is not strictly necessary. Then click “Create download package”:
As you will see, this downloads a zip-file with a few scripts in it. The uup_download_macos.sh script is the one which we will need to run:
Before we can run the script, we need to install a few tools on our Mac first. The easiest method to do this, is by using Homebrew. Start by navigating to the Homebrew website (https://brew.sh/) and copy the command listed under “Install Homebrew”:
Open up a terminal window, paste the command in it and press enter. If asked, enter your user’s password:
jensd@jensds-MacBook-Air ~ % /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ==> Checking for
sudoaccess (which may request your password). Password: ==> This script will install: /opt/homebrew/bin/brew /opt/homebrew/share/doc/homebrew /opt/homebrew/share/man/man1/brew.1 /opt/homebrew/share/zsh/site-functions/_brew /opt/homebrew/etc/bash_completion.d/brew /opt/homebrew ==> The following new directories will be created: /opt/homebrew/Cellar /opt/homebrew/Caskroom ... ==> Next steps: - Run these two commands in your terminal to add Homebrew to your PATH: echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/jensd/.zprofile eval "$(/opt/homebrew/bin/brew shellenv)" - Run `brew help` to get started - Further documentation: https://docs.brew.sh jensd@jensds-MacBook-Air ~ %
At this point, Homebrew is installed on your Mac but you need to add it to your PATH, as suggested in the last output of the previous command:
jensd@jensds-MacBook-Air ~ % echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/jensd/.zprofile jensd@jensds-MacBook-Air ~ % eval "$(/opt/homebrew/bin/brew shellenv)" jensd@jensds-MacBook-Air ~ %
Now that is taken care of, we can install the required tools, using Homebrew, to be able to run the UUP dump script:
jensd@jensds-MacBook-Air ~ % brew tap sidneys/homebrew ==> Tapping sidneys/homebrew ... Tapped 8 casks and 22 formulae (42 files, 157.3KB). jensd@jensds-MacBook-Air ~ % brew install aria2 cabextract wimlib cdrtools sidneys/homebrew/chntpw ==> Downloading https://ghcr.io/v2/homebrew/core/ca-certificates/manifests/2021-09-30-1 ######################################################################## 100.0% ... x86_64cpuid.s:273:10: error: invalid operand cmpq $0,%rax ^ x86_64cpuid.s:274:9: error: unknown token in expression cmoveq %rcx,%rax ^ x86_64cpuid.s:274:9: error: invalid operand cmoveq %rcx,%rax ^ make: *** [x86_64cpuid.o] Error 1 make: *** [build_crypto] Error 1 Do not report this issue to Homebrew/brew or Homebrew/core! These open issues may also help: Mac M1 chntpw not building (Openssl 1.0 requirement not satisfied) https://github.com/sidneys/homebrew-homebrew/issues/2
As you notice, the chntpw tool cannot be installed as it throws an error. The OpenSSL requirement is the issue but the error message also points us to the solution, which is to build OpenSSL ourselves. More details can be found on the Github link that is shared above. In essence, this is what needs to be executed:
jensd@jensds-MacBook-Air ~ % curl -LO https://firstname.lastname@example.org curl -LO https://gist.github.com/minacle/e9dedb8c17025a23a453f8f30eced3da/raw/908b944b3fe2e9f348fbe8b8800daebd87b5966c/chntpw.rb brew install --formula --build-from-source ./email@example.com brew install --formula --build-from-source ./chntpw.rb rm ./firstname.lastname@example.org ./chntpw.rb ... patching file Makefile ==> make 🍺 /opt/homebrew/Cellar/chntpw/0.99.6: 5 files, 296.3KB, built in 2 seconds Removing: /Users/jensd/Library/Caches/Homebrew/chntpw--patch--dbf09ccee4eaf401e2680554990ee924bb0ad1dd7661a3c97d67bf796089fbbe.patch... (211B) jensd@jensds-MacBook-Air ~ %
So far that were quite a lot of steps… But finally we are ready to execute the script which we got from the UUP Dump website. First navigate to the directory where you downloaded and extracted the files, then execute the macOS version of the script:
jensd@jensds-MacBook-Air ~ % cd Downloads jensd@jensds-MacBook-Air Downloads % cd 22000.160_arm64_en-us_professional_fdb8a3c7_convert jensd@jensds-MacBook-Air 22000.160_arm64_en-us_professional_fdb8a3c7_convert % bash uup_download_macos.sh Retrieving aria2 script... 10/22 11:46:10 [NOTICE] Downloading 1 item(s) [#8c33b1 0B/0B CN:1 DL:0B] ... 99.63% done, estimate finish Fri Oct 22 11:51:38 2021 99.86% done, estimate finish Fri Oct 22 11:51:38 2021 Total translation table size: 2048 Total rockridge attributes bytes: 0 Total directory bytes: 0 Path table size(bytes): 10 Max brk space used 0 2198094 extents written (4293 MB) Done. jensd@jensds-MacBook-Air 22000.160_arm64_en-us_professional_fdb8a3c7_convert %
As a result, you should end up with an ISO file in the directory from where you executed the script:
You can move this file to wherever you want, as long as you remember where for the next steps.
Step 2) Downlad and install UTM
Now that we have the ISO which we will use to get Windows installed, we need a way to create a virtual machine in which we can run the installer. There are several options available for this. The more known ones like Parallels or VMWare Fusion for example. Unfortunately these are not free but they should work as well. Instead, I will go for UTM.
UTM, as mentioned in the beginning, offers QEMU-based virtaluzation and emulation for both IOS and macOS. I tried to find what the UTM abbreviation stands for but was not able to find it.
You can download UTM from Github using: https://github.com/utmapp/UTM/releases/latest/download/UTM.dmg
Once downloaded, simply open the .dmg file by double clicking on it and move UTM.app to your Applications folder using Finder:
Then start UTM, simply by launching it as any other application on your Mac.
Step 3) Create a VM for your Windows 11 ARM installation
At this point we have both the ISO file for installing Windows and we have our hypervisor, UTM, ready. Now we need to create a new virtual machine with UTM for use with the next step.
Start UTM and click on “Create a New Virtual Machine”:
In the first tab: Information, choose a name for your VM and optionally choose a matching icon:
Navigate to the second tab: Sytem and select ARM64 (aarch64) as architecture. This matches the architecture of the M1-chip so we will not use emulation. Change the memory slider to have at least 4GB. I did notice that slightly more is really better (I took 6GB here for example). Optionally, click “Show Advanced Settings” and set a number of CPU cores (I chose 4 here) and enable “Force Multicore”:
Now navigate to the Drives tab, click “New Drive” and change the interface to NVMe and give a size of at least 55GB. Then click “New Drive” again, check the removable option and choose “None (Advanced)” as interface:
Selecting None as interface is needed due to an issue/bug in QEMU. I’ve opened this on the UTM Github page but so far a workaround is still needed. Type None allows to specify the required parameters to give an interface for our virtual CD/DVD drive.
To do so, navigate to the QEMU tab and scroll all the way down in the list, until you reach the last line saying New…, then add two lines as follows:
After all these steps, click Save to create the new VM in UTM.
Only thing which is left, is to mount the Windows 11 ARM installation ISO, which we created in the first step to the VM. To do so, select the VM you just created from the list and on the CD/DVD dropdown, choose Browse:
Then navigate to your Downloads folder (or other location where you move the ISO file afterwards) and select the ISO which got created in step 1:
Step 4) Install Windows 11 ARM on your M1-based device
Now that we have our VM created, let’s get it started and run through the Windows 11 installation.
Start the VM by clicking on the large play icon (see previous two images). The VM will boot and you should see a large UTM logo.
Make sure you click in the VM immediately as it will ask to press a key to boot from the ISO:
After pressing any key, the installer will start from the ISO and if all goes well, you should be able to see the standard Windows 11 installer, where you can select a language, locale and keyboard settings:
Set these as desired and click Next.
In the next screen, we need to do some modifications before we can click “Install Now”. Windows 11 has some strict requirements for the hardware it is allowed to run on. As our Macbook, and the VM, does not have Secure Boot nor TPM, we need to work around that by adding some keys in the register.
So on the screen where you seen Install Now, press Shift + F10. It might be that you need to use Fn+F10, depending on how you configured your function keys. This should bring up a command prompt where we can open regedit:
In the registry editor, navigate to: Computer\HKEY_LOCAL_MACHINE\SYSTEM\Setup and add a new key there called LabConfig. To do this, right click on Setup and choose New > Key:
Give it the name LabConfig and in the key, right click and choose New – DWORD (32-bit) Value:
Give the name BypassTPMCheck to this DWORD. Repeat these steps a second time but nowgive the name BypassSecureBootCheck. Then double-click on each of these two DWORDs and change the value to 1. As a result, you should get the following:
Now that’s done, we can close the Registry Editor and the command prompt we opened and continue with the install by clicking “Install Now”:
In the next screens, choose: “I don’t have a product key”, accept the license and choose for: “Custom: Install Windows only (advanced)”. You should end up with the “Where do you want to install Windows?” dialog:
Here you can simply click next and let the installer create the necessary volumes on the virtual drive which we added in UTM. After that, Windows should copy the files to the drive and continue the installation:
In case you run into an issues during the “Getting files read for installation” and the installer ends with an error like 0x800701B1 (Windows cannot install required files. Make sure all files required for installation are available.), Restart the VM and give it another try. This issue is the main reason for the custom QEMU-parameters for the USB-connected virtual CD/DVD drive. They seem to help but the issue still shows in some cases. Two tries at max. should do it normally.
Once this all completes, the VM will reboot and you should be greeted with the following dialog where you need to answer the questions regarding location, keyboard layout, username, password and privacy settings:
After completing the questions, the installation is getting finalized:
and you should end up with your fresh Windows 11 ARM desktop:
Step 5) Perform some post-installation tasks
In the previous steps, we managed to get a working Windows 11 installation on the M1-based device. But if you work a bit with it, you will notice that the system is not working very optimal yet. There is no network/internet connectivity and the resolution is stuck at 800×600.
Both these issues can be resolved by installing the SPICE Guest Tools and QEMU Drivers. These can be downloaded from the Support section on UTMs website:
Open your browser on macOS, navigate to https://mac.getutm.app/support/ and download the guest tools and drivers:
Then in UTM, go to your VM in the list, select it and change the ISO for the virtual CD/DVD drive to the downloaded ISO:
Then in your Windows 11 VM, navigate to the CD/DVD drive and run spice-guest-tools.0.164 (or the version you downloaded):
After that, you will notice that the network adapter will be available and connected:
After this step you can also change the resolution and size of the VM. To do so, right click on the desktop and choose “Display settings”. You will see that you have an additional virtual display now. Here you need to scroll down and choose to “Show only on 1”:
The display will flicker and you should end up with a better resolution already. When asked, choose to keep the changes. If desired, you can change the resolution to a higher value but you might notice that there can be issues with the mouse pointer being misaligned.
Best to do at this stage is a reboot. If you don’t manage with the mouse, just press Alt+F4 and reboot.
Step 6) Profit!
Using the VM directly might not give you the expected feeling. It feels a bit bulky/laggy although the performance really isn’t that bad. To my idea it works a lot better if you enable remote desktop and connect to it with Microsoft Remote Desktop from macOS instead.
First enable remote access on your VM:
Find the IP-address that your VM received. You can do so by opening a command prompt and run “ipconfig” or use the Settings dialogs:
On macOS, install Microsoft Remote Desktop, you can find it in the App Store and add a PC with the IP-address which you found (192.168.64.4 in my case):
Connect to the VM’s IP address using Microsoft Remote Desktop and enter your Windows username and password. This will give you a good looking fullscreen Windows 11 experience:
Looking briefly at the performance, with the 4 cores reserved for the VM and 6GB of RAM, the scores I managed to get from some basic benchmarks are really above expectation.
I’ll probably do another post going a bit deeper in performance but this is what I saw for Geekbench 5 for example, which is able to test on AArch64 native:
Browserbench gave a nice result as well:
As you can see, a machine with these scores is not a punishment to work with for sure.
Although it takes quite some steps and time, this process should allow you to get a Windows 11 ARM-based VM on your M1 based device.