English | Japanese
Last-Update: June 8, 2021.
This document describes how to run Windows 10 for ARM and Linux operating systems properly on Apple Silicon (M1) Mac by using open source software only. The combination of QEMU and Alexander Graf's Hypervisor.framework support patch allows us to run Windows 10 and Linux for 64-bit ARM processors on M1 Mac efficiently. Several webpages such as How to run Windows 10 on ARM or Ubuntu for ARM64 in QEMU on Apple Silicon Mac and QEMU on M1 Mac describe how to set up a QEMU environment with Alex's patch. While they are helpful for the first trial, additional effort is needed to realize a proper QEMU environment that can be used for our daily business. This document attempts to provide a step-by-step instruction to build a QEMU environment with proper internet connection, Japanese keyboard support, and file sharing between the host and guest OSes.
In this document, we build everything from the source. Hence, a software development environment is required to follow the instruction of this document. This document assumes that the readers have a familiarity with the command line tools for software development.
Since all the software this document uses evolve very rapidly, the situation will change day by day. I will update this document when I found the changes.
I wrote homebrew formulae that automatically perform the build of Samba, QEMU, and OVMF described below. By using them, you can skip the steps until "Set up Windows 10 ARM."
To install Samba and QEMU, run the following commands:
brew tap uenob/qemu-hvf
brew install --head qemu-hvf
brew install ovmf
Add /opt/homebrew/opt/qemu-hvf/bin
to PATH
.
PATH=/opt/homebrew/opt/qemu-hvf/bin:$PATH
Install Homebrew and Xcode Command Line Tools.
By using the brew
command, install the following prerequisite tools and libraries.
brew install glib ninja pkgconfig pixman python
All the libraries and tools should be arm64 version and installed in /opt/homebrew
.
If you have some of them installed in /usr/local
, I suggest you to uninstall them from /usr/local
before going to the next step.
It would be better to create a directory for building software.
mkdir ~/qemu
cd ~/qemu
The directory created here is the final destination of the software we will build. In the following steps, we do not install the software. We execute files in the build directory.
To enable file sharing between the host and guests, Samba's smbd
is needed.
macOS has its own smbd
but it is not compatible with Samba.
Unfortunately, Samba is not included in Homebrew; therefore, we need to build it from its source.
At first, download the source package of Samba and additional Perl module.
curl -O https://download.samba.org/pub/samba/stable/samba-4.14.3.tar.gz
curl -O https://cpan.metacpan.org/authors/id/W/WB/WBRASWELL/Parse-Yapp-1.21.tar.gz
Build the Perl module and set the PERL5LIB
environment variable so that perl
can find it.
tar -xzvf Parse-Yapp-1.21.tar.gz
cd Parse-Yapp-1.21
perl Makefile.PL
make
export PERL5LIB="$PWD/blib/lib"
cd ..
Expand the source of Samba.
tar -xzvf samba-4.14.3.tar.gz
cd samba-4.14.3
Apply the following patch by hand.
--- samba-4.14.3/lib/util/charset/charset_macosxfs.c.orig 2021-01-21 22:20:40.000000000 +0900
+++ samba-4.14.3/lib/util/charset/charset_macosxfs.c 2021-04-21 14:00:43.000000000 +0900
@@ -29,6 +29,7 @@
* source.
*/
+#include "util/debug.h"
#include "replace.h"
#include "charset.h"
#include "charset_proto.h"
Build smbd
from the source and remember the path to smbd
in the SMBD_PATH
variable.
./configure --prefix="$PWD/o" \
--disable-python --without-ad-dc \
--without-libarchive --without-gpgme \
--without-acl-support
make bin/smbd
SMBD_PATH=$PWD/bin/smbd
cd ..
We do not type make install
; because of dynamic library paths, Samba works only in the build directory.
We use the latest development version of QEMU, which includes many improvements and bugfixes, as the base of our setup. Unfortunately, Alexander Graf's patch cannot be applied to the latest version of QEMU. I have merged the patch to the latest QEMU and made the result available from my GitHub repository. In this document, we obtain QEMU's source from that repository.
git clone --branch hvf https://github.com/uenoB/qemu.git
cd qemu
Update the slirp library to the latest version. Without this, QEMU's user network does not work properly. (c.f. https://gitlab.freedesktop.org/slirp/libslirp/-/issues/35)
git submodule update --init slirp
cd slirp
git checkout v4.5.0
cd ..
Apply the following patch by hand so that QEMU can be built with the updated slirp library.
--- a/meson.build
+++ b/meson.build
@@ -1525,6 +1525,8 @@ if have_system
slirp_deps = []
if targetos == 'windows'
slirp_deps = cc.find_library('iphlpapi')
+ elif targetos == 'darwin'
+ slirp_deps = cc.find_library('resolv')
endif
slirp_conf = configuration_data()
slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
Build QEMU from the source.
mkdir build
cd build
../configure --prefix="$PWD/o" \
--target-list=aarch64-softmmu,x86_64-softmmu \
--enable-cocoa \
--smbd="$SMBD_PATH"
make
Add the current directory (i.e, the build directory of QEMU) to PATH
.
PATH="$PWD:$PATH"
A Linux system is needed to build OVMF, the UEFI firmware image. Here we set up Ubuntu, served also as a demonstration of QEMU.
Create the directory for the virtual machine image of Ubuntu and change directory to it.
mkdir -p ~/qemu/vm/Ubuntu
cd ~/qemu/vm/Ubuntu
Create a hard disk image for the Ubuntu system.
qemu-img create -f qcow2 disk.qcow2 20G
Download Ubuntu Desktop 20.04 LTS for amd64 from the Download Ubuntu Desktop page.
You will find ubuntu-20.04.2.0-desktop-amd64.iso
downloaded in the Downloads folder.
Launch the Ubuntu installer on QEMU by the following command:
qemu-system-x86_64 \
-smp 1 \
-m 4096 \
-rtc base=localtime,clock=rt \
-device virtio-net,netdev=net \
-netdev user,id=net,smb="$HOME" \
-drive file=disk.qcow2,format=qcow2,if=virtio \
-drive file="$HOME/Downloads/ubuntu-20.04.2.0-desktop-amd64.iso",media=cdrom
A window of QEMU will open and you will find the Ubuntu installer running in it.
Proceed the installation steps of Ubuntu as usual. Minimal installation should be preferred for fast completion.
After the installation process has completed and you logged in to Ubuntu as a user, open Terminal and run the following command to mount the home directory of the host system to the guest Ubuntu system:
sudo apt install cifs-utils
sudo mount -t cifs -o user=,pass= //10.0.2.4/qemu /mnt
All the commands in this step must be proceeded on Ubuntu.
Install the prerequisite tools to build OVMF.
sudo apt install git iasl python3 python3-distutils uuid-dev make g++ nasm gcc-aarch64-linux-gnu
Obtain the latest stable version of EDK II from GitHub.
git clone --branch edk2-stable202011 https://github.com/tianocore/edk2.git
cd edk2
git submodule update --init --recursive
Build the OVMF firmware for amd64 and arm64 from the source.
source edksetup.sh
make -C BaseTools
build -a X64 -t GCC5 -p OvmfPkg/OvmfPkgX64.dsc
GCC5_AARCH64_PREFIX=aarch64-linux-gnu- build -a AARCH64 -t GCC5 -p ArmVirtPkg/ArmVirtQemu.dsc
Copy the UEFI images to the host.
tar -C Build -cf - \
ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/QEMU_{EFI,VARS}.fd \
OvmfX64/DEBUG_GCC5/FV/OVMF_{CODE,VARS}.fd \
| sudo tar -C /mnt/qemu -xvf -
Shut down the Ubuntu system.
Join the insider program and download the Windows 10 ARM VDMX image from the Windows Insider Preview Downloads page.
You will find Windows10_InsiderPreview_Client_ARM64_en-us_21354.VHDX
downloaded in the Downloads folder.
In addition to the disk image, download the following.
- https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.190-1/virtio-win-0.1.190.iso for the virtio Ethernet and SCSI drivers.
- https://github.com/ubenmackin/ACVM/releases/download/v1.5/viogpudo.zip for the virtio-gpu driver.
Create the directory for the virtual machine image of Windows and change directory to it.
mkdir -p ~/qemu/vm/Windows
cd ~/qemu/vm/Windows
Convert viogpudo.zip
to an ISO image.
unzip ~/Downloads/viogpudo.zip
hdiutil makehybrid -o viogpudo viogpudo
Create a dummy disk image for setting up virtio SCSI driver.
qemu-img create -f qcow2 dummy.qcow2 1G
Convert the VHDX disk image to the qcow2 format.
qemu-img convert -p -O qcow2 \
~/Downloads/Windows10_InsiderPreview_Client_ARM64_en-us_21354.VHDX \
disk.qcow2
Create UEFI images.
qemu-img convert -f raw -O qcow2 \
$HOME/qemu/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/QEMU_EFI.fd \
pflash0.img
qemu-img convert -f raw -O qcow2 \
$HOME/qemu/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/QEMU_VARS.fd \
pflash1.img
qemu-img resize pflash0.img 64M
qemu-img resize pflash1.img 64M
Launch Windows by the following command.
qemu-system-aarch64 \
-machine virt,highmem=off \
-accel hvf \
-smp 1 \
-m 4096 \
-rtc base=localtime,clock=rt \
-drive file=pflash0.qcow2,format=qcow2,if=pflash \
-drive file=pflash1.qcow2,format=qcow2,if=pflash \
-device ramfb \
-device qemu-xhci \
-device usb-kbd \
-device usb-tablet \
-audiodev coreaudio,id=audio \
-device intel-hda \
-device hda-output,audiodev=audio \
-drive file=disk.qcow2,format=qcow2,if=none,id=boot,cache=writethrough \
-device nvme,drive=boot,serial=boot
Make sure that sending diagnostic data to Microsoft is turned on, or you cannot obtain the further updates of insider builds.
After Windows has been launched, start Command Prompt (Admin) and type the following command so that we enter the test mode and can install unsigned drivers.
bcdedit -set TESTSIGNING ON
Shut down Windows.
Reboot Windows by the following command:
qemu-system-aarch64 \
-machine virt,highmem=off \
-accel hvf \
-smp 1 \
-m 4096 \
-rtc base=localtime,clock=rt \
-drive file=pflash0.qcow2,format=qcow2,if=pflash \
-drive file=pflash1.qcow2,format=qcow2,if=pflash \
-device ramfb \
-device qemu-xhci \
-device usb-kbd \
-device usb-tablet \
-audiodev coreaudio,id=audio \
-device intel-hda \
-device hda-output,audiodev=audio \
-device virtio-net,netdev=net \
-netdev user,id=net \
-drive file=disk.qcow2,format=qcow2,if=none,id=boot,cache=writethrough \
-device nvme,drive=boot,serial=boot \
-drive file=dummy.qcow2,format=qcow2,if=virtio \
-drive file="$HOME/Downloads/virtio-win-0.1.190.iso",media=cdrom,if=none,id=cd1 \
-device usb-storage,drive=cd1 \
-drive file=viogpudo.iso,media=cdrom,if=none,id=cd2 \
-device usb-storage,drive=cd2
After Windows is booted, install Ethernet and SCSI drivers by the following steps:
- Start Device Manager.
- Look for an unknown Ethernet adapter and double-click it.
- Click "Update Drivers", "Browse my computer for drivers", and input
D:\NetKVM\w10\ARM64
. - Install "Red Hat VirtIO Ethernet Adapter".
- Look for an unknown SCSI controller and double-click it.
- Click "Update Drivers", "Browse my computer for drivers", and input
D:\viostor\w10\ARM64
. - Install "Red Hat VirtIO SCSI Controller".
- Open E: drive in File Explorer and execute
InstallCerts and Driver.bat
.
Then, shut down Windows.
Now, you successfully finished the set up of Windows. Boot Windows by the following command for daily use:
qemu-system-aarch64 \
-machine virt,highmem=off \
-accel hvf \
-smp 1 \
-m 4096 \
-rtc base=localtime,clock=rt \
-drive file=pflash0.qcow2,format=qcow2,if=pflash \
-drive file=pflash1.qcow2,format=qcow2,if=pflash \
-display default,show-cursor=on \
-device virtio-gpu \
-device qemu-xhci \
-device usb-kbd \
-device usb-tablet \
-audiodev coreaudio,id=audio \
-device intel-hda \
-device hda-output,audiodev=audio \
-device virtio-net,netdev=net \
-netdev user,id=net,smb="$HOME" \
-drive file=disk.qcow2,format=qcow2,if=virtio
Confirm the following:
- The network icon in the task bar indicates the Internet connection.
- The home directory of the host is found in
\\10.0.2.4\qemu
. - If you use a jp106 keyboard, you can type backslash and underscore as expected.
Enjoy!