Create a Linux Virtual Machine on M1 Macbook
In this post I’ll outline my process for setting up a Linux virtual machine using QEMU on an M1 Macbook Pro.
Reference:
[SUCCESS] Virtualize Windows 10 for ARM on M1 with Alexander Graf’s qemu hypervisor patch
Install QEMU: #
At the time of writing brew install -s qemu
fails on my M1 Macbook. Until the Homebrew formula is updated, we need to compile QEMU manually.
Install some dependencies:
brew install -s pkg-config glib pixman ninja
Clone and patch QEMU:
sudo git clone https://git.qemu.org/git/qemu.git /opt/qemu
sudo chown -R $USER /opt/qemu
cd /opt/qemu
mkdir bin && cd bin
../configure
make -j6
Add the /opt/qemu/bin
directory to your PATH (might want to add this to your shell’s config files to make this persist):
export PATH="/opt/qemu/bin:$PATH"
Install Libvirt: #
Let’s also install libvirt to make managing QEMU VMs easier (brew install -s libvirt
also doesn’t work at the time of writing):
brew install -s meson libxml2 zlib
sudo git clone https://gitlab.com/libvirt/libvirt.git /opt/libvirt
sudo chown -R $USER /opt/libvirt
Since I’m using a custom Homebrew directory, I had to set the $PKG_CONFIG_PATH
variable for the libxml2 and zlib files to be found properly. For example:
HOMEBREW_DIR="$HOME/opt/homebrew"
export PKG_CONFIG_PATH="$HOMEBREW_DIR/Library/Homebrew/os/mac/pkgconfig/11.1/"
I was able to find the directory for the PKG_CONFIG_PATH
variable with the following commands:
find $HOMEBREW_DIR -name "libxml-2.0.pc"
find $HOMEBREW_DIR -name "zlib.pc"
Let’s compile libvirt to /opt/libvirt/usr
:
cd /opt/libvirt
mkdir -p /opt/libvirt/usr
meson build --prefix=/opt/libvirt/usr
ninja -C build
mv /opt/libvirt/build /opt/libvirt/usr
Setup the VM: #
I will assume all the resources for the VM will be in a directory called /opt/virtual-machine
:
sudo mkdir -p /opt/virtual-machine
sudo chown -R $USER /opt/virtual-machine
Download Debian Image: #
curl 'https://cdimage.debian.org/cdimage/release/current/arm64/iso-dvd/debian-10.7.0-arm64-DVD-1.iso' -o /opt/virtual-machine/debian-arm64.iso
Setup the Disk File: #
qemu-img create /opt/virtual-machine/debian-vm.img 40G
Setup EFI Firmware: #
Download the following zip file:
https://mega.nz/file/QYB0QTrC#p6IMBJlFqqNKuGonwrDkPOVKQj8yHCVgiLOYVaGvs4M
Unzip it and move the contents of the qemu-m1
directory to /opt/virtual-machine/
:
cp -r qemu-m1/* /opt/virtual-machine/
Start the VM: #
Create a script in /opt/virtual-machine/start.sh
with the following contents:
#!/usr/bin/env bash
root_dir="/opt/virtual-machine"
cd "${root_dir}"
DYLD_LIBRARY_PATH="${root_dir}" "${root_dir}"/qemu-system-aarch64 \
-M virt \
-accel hvf \
-m 1G \
-smp 1 \
-cpu max \
-device ramfb \
-serial stdio \
-drive file="${root_dir}"/debian-arm64.iso,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="${root_dir}/debian-vm.img",media=disk,cache=unsafe \
-drive file="${root_dir}"/vars-template-pflash.raw,if=pflash,index=1 \
-bios ${root_dir}/QEMU_EFI.fd
Make the script executable:
chmod +x /opt/virtual-machine/start.sh
Now run the script:
/opt/virtual-machine/start.sh
mac linux