Skip to content

Instantly share code, notes, and snippets.

@igorvoltaic
Last active July 4, 2024 22:41
Show Gist options
  • Save igorvoltaic/df226aacd84cb495d15d521e20544a53 to your computer and use it in GitHub Desktop.
Save igorvoltaic/df226aacd84cb495d15d521e20544a53 to your computer and use it in GitHub Desktop.
QEMU (7.1.0) Virtualisation Examples on Mac M1

arm64 Linux VM on Mac M1 using QEMU

INSTALLATION

qemu-system-aarch64 \
    -cpu max -m 8G \
    -machine virt,accel=hvf \
    -M q35 \
    -smp 4,sockets=1,cores=4,threads=1 \
    -device virtio-gpu-pci \
    -display default,show-cursor=on \
    -device qemu-xhci \
    -device usb-kbd \
    -device usb-tablet \
    -drive "file=parrot.qcow2,if=none,id=drive0,cache=writeback" \
    -device virtio-blk,drive=drive0,bootindex=0 \
    -boot d \
    -cdrom Parrot-architect-5.1.1_arm64.iso

USAGE

efi_firm="$(dirname $(which qemu-img))/../share/qemu/edk2-aarch64-code.fd"
qemu-system-aarch64 \
    -cpu max -m 8G \
    -machine virt,accel=hvf \
    -smp 4,sockets=1,cores=4,threads=1 \
    -device qemu-xhci,id=usb-bus \
    -device usb-tablet,bus=usb-bus.0 \
    -device usb-mouse,bus=usb-bus.0 \
    -device usb-kbd,bus=usb-bus.0 \
    -device virtio-keyboard-pci \
    -device virtio-gpu-pci \
    -display default,show-cursor=on \
    -audio model=hda,driver=coreaudio \
    -nic hostfwd=tcp::22-:22,hostfwd=tcp::80-:80\
    -bios $efi_firm \
    -drive "file=parrot.qcow2,if=none,id=drive0,cache=writeback" \
    -device virtio-blk,drive=drive0,bootindex=0

arm64 Windows VM on Mac M1 using QEMU (WIP)

new_windows.sh:

#!/bin/bash

windows10vhdx="disk_images/Windows10_InsiderPreview_Client_ARM64_en-us_21354.VHDX windows.qcow2"
virtio-win-iso="disk_images/virtio-win-0.1.190.iso"

efi_firm="$(dirname $(which qemu-img))/../share/qemu/edk2-aarch64-code.fd"

dd if=/dev/zero conv=sync bs=1m count=64 of=windows_ovmf_vars.fd

qemu-img convert -O qcow2 "$windows10vhdx" windows.qcow2

echo "starting"

qemu-system-aarch64 \
  -machine virt,accel=hvf,highmem=off \
  -cpu cortex-a72 -smp 4 -m 4G \
  -device ramfb \
  -device qemu-xhci,id=usb-bus \
  -device usb-tablet,bus=usb-bus.0 \
  -device usb-mouse,bus=usb-bus.0 \
  -device usb-kbd,bus=usb-bus.0 \
  -nic user,model=virtio \
  -drive format=raw,file="$efi_firm",if=pflash,readonly=on \
  -drive format=raw,file=windows_ovmf_vars.fd,if=pflash \
  -drive if=none,media=disk,id=drive0,format=qcow2,file=windows.qcow2 \
  -device nvme,drive=drive0,serial=drive0,bootindex=0 \
  -device usb-storage,drive=drive2,removable=true,bootindex=2 \
  -drive if=none,media=cdrom,id=drive2,file="$virtio-win-iso"

# To enable networking after installing:
# 1. run `bcdedit.exe -set TESTSIGNING ON`
# 2. Open device manager and find the unknown ethernet device.
# 3. Choose to update and search for the driver on the computer.
# 4. Navigate to and select D:\NetKVM\w10\ARM64

You will need to download the Windows VHDX from here and the latest virtio-win iso from here

Be sure to update windows10vhdx and virtio-win-iso to have the proper paths to the VHDX and iso respectively. I created a directory within my vm directory called "disk_images" and put them there for organization's sake.

start_windows.sh:

#!/bin/bash

efi_firm="$(dirname $(which qemu-img))/../share/qemu/edk2-aarch64-code.fd"

echo "starting"

qemu-system-aarch64 \
  -machine virt,accel=hvf,highmem=off \
  -cpu cortex-a72 -smp 4 -m 4G \
  -device ramfb \
  -device qemu-xhci,id=usb-bus \
  -device usb-tablet,bus=usb-bus.0 \
  -device usb-mouse,bus=usb-bus.0 \
  -device usb-kbd,bus=usb-bus.0 \
  -nic user,model=virtio \
  -drive format=raw,file="$efi_firm",if=pflash,readonly=on \
  -drive format=raw,file=windows_ovmf_vars.fd,if=pflash \
  -drive if=none,media=disk,id=drive0,format=qcow2,file=windows.qcow2 \
  -device nvme,drive=drive0,serial=drive0,bootindex=0 \

If you want to attach a second drive to the machine, just add it by copying the last two lines and modify the drive id and boot index in each.

For example:

-drive if=none,media=disk,id=drive1,format=qcow2,file=foo.qcow2 \
-device nvme,drive=drive1,serial=drive1,bootindex=1 \

Something you could do with this is create an extra drive that can be used for multiple different machines. If you do that, however, be sure to only run one machine at any given time because I'm sure it would cause severe corruption if both were to write to the drive at the same time.

Another thing to be aware of: Unfortunately ARM64 Windows doesn't have virtio-gpu drivers yet (as far as I can tell, and I've searched hard for them) so we're stuck with ramfb. I'm not entirely sure, but I think this means everything is rendered in software. Additionally, my machine appears to be restricted to three different resolutions: 640x480, 800x600, and 1024x768. You can set this by hitting escape on the "TianoCore" screen before the windows loading dot circle thing.

x86_64 (amd64) Linux VM on Mac M1 using QEMU

INSTALLATION

qemu-system-x86_64 \
    -cpu qemu64 -m 8G \
    -M q35 \
    -smp 4,sockets=1,cores=4,threads=1 \
    -device virtio-gpu-pci \
    -display default,show-cursor=on \
    -device qemu-xhci \
    -device usb-kbd \
    -device usb-tablet \
    -drive "file=parrot.qcow2,if=none,id=drive0,cache=writeback" \
    -device virtio-blk,drive=drive0,bootindex=0 \
    -boot d \
    -cdrom Parrot-architect-5.1.1_amd64.iso

USAGE

qemu-system-x86_64 \
    -cpu qemu64 -m 8G \
    -M q35 \
    -smp 4,sockets=1,cores=4,threads=1 \
    -device qemu-xhci,id=usb-bus \
    -device usb-tablet,bus=usb-bus.0 \
    -device usb-mouse,bus=usb-bus.0 \
    -device usb-kbd,bus=usb-bus.0 \
    -device virtio-keyboard-pci \
    -device virtio-gpu-pci \
    -display default,show-cursor=on \
    -audio model=hda,driver=coreaudio \
    -nic hostfwd=tcp::22-:22,hostfwd=tcp::80-:80\
    -bios $efi_firm \
    -drive "file=parrot.qcow2,if=none,id=drive0,cache=writeback" \
    -device virtio-blk,drive=drive0,bootindex=0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment