Skip to content

Instantly share code, notes, and snippets.

@ctsrc
Forked from niw/README.en.md
Last active October 9, 2025 20:37
Show Gist options
  • Save ctsrc/a1f57933a2cde9abc0f07be12889f97f to your computer and use it in GitHub Desktop.
Save ctsrc/a1f57933a2cde9abc0f07be12889f97f to your computer and use it in GitHub Desktop.
Guide: Run FreeBSD 13.1-RELEASE for ARM64 in QEMU on Apple Silicon Mac (MacBook Pro M1, etc) with HVF acceleration (Hypervisor.framework)

How to run FreeBSD 13.0-BETA1 for ARM64 in QEMU on Apple Silicon Mac (MacBook Pro M1, etc)

FreeBSD 13.0-BETA1 for ARM64 boot in QEMU on Apple Silicon Mac screenshot

This guide was adapted from https://gist.github.com/niw/e4313b9c14e968764a52375da41b4278#running-ubuntu-server-for-arm64

Running FreeBSD 13.0-BETA1 for ARM64

  1. Install Xcode from App Store or install Command Line Tools on your Mac running on Apple Silicon.

    xcode-select --install
    
  2. Install Homebrew and QEMU dependencies.

    https://brew.sh/

    brew install ninja pkgconfig glib pixman libusb libssh zstd usbredir
    
  3. Clone QEMU source code with patches applied by patchew.

    mkdir -p ~/src/
    cd ~/src/
    git clone https://github.com/patchew-project/qemu.git
    
  4. Checkout tag that has Hypervisor.framework patches

    cd qemu
    git checkout patchew/[email protected]
    

    See https://patchew.org/QEMU/[email protected]/ for details.

  5. Build QEMU

    mkdir build/
    cd build/
    ../configure --target-list=aarch64-softmmu --enable-cocoa
    make -j
    
  6. Download pre-build EDK II OVMF EFI image for QEMU.

    This EFI image is built from stable202011 tag with additional resolutions in QemuRamfb.c.

    https://gist.github.com/niw/4f1f9bb572f40d406866f23b3127919b/raw/f546faea68f4149c06cca88fa67ace07a3758268/QEMU_EFI-cb438b9-edk2-stable202011-with-extra-resolutions.tar.gz

    To build it from the source code for adding more resolutions, see the following section.

  7. Prepare pflash for non-volatile variable store, such as screen resolution.

    mkdir ~/qemu-vm/
    cd ~/qemu-vm/
    tar xvf ~/Downloads/QEMU_EFI-cb438b9-edk2-stable202011-with-extra-resolutions.tar.gz
    dd if=/dev/zero of=pflash0.img bs=1m count=64
    dd if=/dev/zero of=pflash1.img bs=1m count=64
    dd if=QEMU_EFI.fd of=pflash0.img conv=notrunc
    dd if=QEMU_VARS.fd of=pflash1.img conv=notrunc
    
    • This step is optional, you can use -bios QEMU_EFI.fd instead of -drive ...if=pflash lines in the next step, but in that case, any changes in EFI will not be persistent.
  8. Download FreeBSD 13.0-BETA1 for ARM64 raw VM image xz-compressed file

    https://download.freebsd.org/ftp/releases/VM-IMAGES/13.0-BETA1/aarch64/Latest/FreeBSD-13.0-BETA1-arm64-aarch64.raw.xz

  9. Decompress xz-compressed file, keeping a copy of the original compressed file

    Keeping a copy of the original file is convenient because then you can use it if you want to create additional VMs later. Just be careful not to overwrite the image of your first VM when you want to make a second VM though :P

    mv ~/Downloads/FreeBSD-13.0-BETA1-arm64-aarch64.raw.xz .
    unxz -k ~/Downloads/FreeBSD-13.0-BETA1-arm64-aarch64.raw.xz
    
  10. Run your FreeBSD 13.0-BETA1 for ARM64 VM

    ~/src/qemu/build/qemu-system-aarch64 \
      -M virt,highmem=off \
      -accel hvf \
      -cpu cortex-a72 \
      -smp 4 \
      -m 4096 \
      -drive file=pflash0.img,format=raw,if=pflash,readonly=on \
      -drive file=pflash1.img,format=raw,if=pflash \
      -device virtio-gpu-pci \
      -display default,show-cursor=on \
      -device qemu-xhci \
      -device usb-kbd \
      -device usb-tablet \
      -device intel-hda \
      -device hda-duplex \
      -drive file=FreeBSD-13.0-BETA1-arm64-aarch64.raw,if=virtio,cache=writethrough \
      -nographic \
      -serial mon:stdio
    

A screenshot of FreeBSD 13.0-BETA1 for ARM64 console in QEMU on Apple Silicon Mac, showing the tail end of the boot output along with the login prompt and the output of uname -a Another screenshot of FreeBSD 13.0-BETA1 for ARM64 console in QEMU on Apple Silicon Mac, this time showing that networking is working and is able to connect over HTTP to the website www.example.com

@BrettDong
Copy link

DNS is working but ping gives weird result:
螢幕截圖 2021-02-11 下午4 52 46

@BrettDong
Copy link

@felipedbene
Copy link

I have one of these running in a actual nano pi r2s but the problem is that they only way I can reach it is using ssh but i dunno the image's default user and password, does anybody know it, by any chance?

@BrettDong
Copy link

Username is root and there is no password.

@BrettDong
Copy link

Good news for everyone! There is some update in https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=237441 regarding the network issue:

It appears this is a libslirp issue on macOS.
Rebuilding QEMU with slirp updated to include https://gitlab.freedesktop.org/slirp/libslirp/-/commit/7271345efe182199acaeae602cb78a94a7c6dc9d fixes this issue for me.
See also https://gitlab.freedesktop.org/slirp/libslirp/-/issues/35
I've filed Homebrew/homebrew-core#73517

@ctsrc
Copy link
Author

ctsrc commented Sep 20, 2021

@BrettDong

I've filed Homebrew/homebrew-core#73517

I tried to build qemu with the most recent hvf patches now and at the same time specifying --enable-slirp=system when running configure.

But I am still getting the same kind of errors inside of the FreeBSD VM when I try to ping 1.1.1.1.

Is there something else one needed to do in order to fix this issue that I missed? My homebrew installed libslirp is version 4.6.1 so it should have the patch.

@sneak
Copy link

sneak commented Aug 4, 2022

Funnily enough, this tutorial uses the linux-style dd numeric syntax (lowercase M) which fails on macOS (I think it inherited dd from freebsd a looong time ago) and needs bs=1M (not bs=1m).

Running the commands as-is on current macOS results in:

dd: invalid number: ‘1m’
dd: invalid number: ‘1m’

@ctsrc
Copy link
Author

ctsrc commented Aug 4, 2022

@sneak What version of macOS are you running? The dd commands given in the guide run as they should on macOS Monterey Version 12.5

Also, what is the output for you of the following?

which dd

You should get the following output:

/bin/dd

If you are getting a different output, and you are using the same version of macOS that I mentioned, then you are not using the dd that ships with macOS. In which case, make sure you are using the dd that ships with macOS.

@dmilith
Copy link

dmilith commented Aug 4, 2022

This guide will not work on M1 macs. Qemu 7.0 has a regression (6.2 worked just fine) and you have to use another build:

# Install QEmu for Mac M1:
#
brew tap uenob/qemu-hvf
brew install --head qemu-hvf

# and then you may want to start headless vm like this:

/opt/homebrew/opt/qemu-hvf/bin/qemu-system-aarch64 \
    -M virt,accel=hvf,highmem=off \
    -m 12288 \
    -smp cores=4 \
    -cpu cortex-a72 \
    -drive file=edk2-aarch64-code.fd,if=pflash,format=raw,readonly=on \
    -drive file=freebsd13.qcow2,format=qcow2 \
    -nographic \
    -device virtio-net-device,netdev=en0 \
    -netdev user,id=en0,hostfwd=tcp::4445-:22 \
    -serial tcp::4444,server,telnet,nowait \
    -pidfile freebsd13.pid

@ctsrc
Copy link
Author

ctsrc commented Aug 5, 2022

@dmilith What do you mean it won't work? I am running qemu 7.0 as shown in the output of the guide, running on MacBook Pro (13-inch, M1, 2020).

I see that you are using the highmem=off argument. With qemu 7.0 you must run without that part.

Please install qemu 7.0 and follow the guide step by step and you will see that it does work.

@astreknet
Copy link

astreknet commented Aug 19, 2022

Tested on MacBook Air M2, works fine.
I just tested OpenBSD too:
https://gist.github.com/astreknet/4860e3362ad98e1116f0a970b99e2afc

@superbonaci
Copy link

This guide will not work on M1 macs. Qemu 7.0 has a regression (6.2 worked just fine) and you have to use another build:

# Install QEmu for Mac M1:
#
brew tap uenob/qemu-hvf
brew install --head qemu-hvf

# and then you may want to start headless vm like this:

/opt/homebrew/opt/qemu-hvf/bin/qemu-system-aarch64 \
    -M virt,accel=hvf,highmem=off \
    -m 12288 \
    -smp cores=4 \
    -cpu cortex-a72 \
    -drive file=edk2-aarch64-code.fd,if=pflash,format=raw,readonly=on \
    -drive file=freebsd13.qcow2,format=qcow2 \
    -nographic \
    -device virtio-net-device,netdev=en0 \
    -netdev user,id=en0,hostfwd=tcp::4445-:22 \
    -serial tcp::4444,server,telnet,nowait \
    -pidfile freebsd13.pid

With QEMU 7.2 it works perfectly fine but probably it's a bit outdated.

@ysmolski
Copy link

ysmolski commented Apr 1, 2023

Ran exactly like explained in the guide, but only on qemu 7.2. While idle, FreeBSD creates load ~200% CPU on my host machine. Is it supposed to be like this?

Update:
I found a solution - simply add this line: kern.hz=100 in /boot/loader.conf
Source: https://gitlab.com/qemu-project/qemu/-/issues/959

@superbonaci
Copy link

Ran exactly like explained in the guide, but only on qemu 7.2. While idle, FreeBSD creates load ~200% CPU on my host machine. Is it supposed to be like this?

Update: I found a solution - simply add this line: kern.hz=100 in /boot/loader.conf Source: https://gitlab.com/qemu-project/qemu/-/issues/959

That's inside FreeBSD root filesystems isn't it?

@ysmolski
Copy link

ysmolski commented Apr 6, 2023

That's inside FreeBSD root filesystems isn't it?

Yes, on the guest machine (inside qemu) that runs FreeBSD. So this is a boot file config for the guest FreeBSD.

@bsdimp
Copy link

bsdimp commented Dec 17, 2023

For some reason, I had to do
root@freebsd:~ # efibootmgr -a -c -l /boot/efi/EFI/BOOT/bootaa64.efi -L FreeBSD-14
to get a boot entry for FreeBSD. Not sure why this wasn't the default after the first boot...

@ylluminate
Copy link

Has anyone gotten X running with or without acceleration?

@cormega2000
Copy link

On a M1 Mac with 14.1 absolut perfect

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment