FreeBSD on a Raspberry Pi CM4

Introduction
Procedure
References

Introduction

This article describes how to run FreeBSD on a Raspberry Pi Compute Module 4 (CM4). The IO board used is the Waveshare CM4-IO-BASE-B, but it also works with the official Raspberry Pi Compute Module 4 IO Board.

Update: There were too many hurdles to make this usable: PWM fan speed, slow network performance, and random ARM kernel panics. I moved on. See References at the bottom.

The default image downloaded from FreeBSD.org will either reboot infinitely or refuse to recognize the USB keyboard no matter how much you tweak config.txt with magic spells that only work on Linux.

The solution is to overlay files from FreeBSD’s rpi-firmware package onto the writable image and configure config.txt appropriately.

The other problem is storage. Here are two CM4 module configurations I tried:

Procedure

This procedure assumes you have an existing FreeBSD system and a Mac.
  1. Download and install the Raspberry Pi Imager from raspberrypi.com onto a Mac.
  2. Download a RPI image from FreeBSD.org onto your existing FreeBSD system such as FreeBSD-14.2-RELEASE-arm64-aarch64-RPI.img.xz with a version number that matches your existing FreeBSD system. You can upgrade later.
  3. Install the rpi-firmware package with pkg install rpi-firmware on your existing FreeBSD system. The package manager prints out the details:
    The rpi-firmware package installs files to /usr/local/share/rpi-firmware/.
    To update the firmware used to boot, copy these files to /boot/msdos,
    and then copy the appropriate config_.txt file to /boot/msdos/config.txt.
    For example, on a Raspberry Pi 4 Model B,
      cp -pr /usr/local/share/rpi-firmware/* /boot/msdos/
      cp /boot/msdos/config_rpi4.txt /boot/msdos/config.txt
    
  4. Mount the uncompressed RPI image on your FreeBSD system so that you can alter its contents.
    # mdconfig -a -t vnode -f FreeBSD-14.2-RELEASE-arm64-aarch64-RPI.img -u 0
    This will mount the different image partitions into /dev devices md0, md0s1, md0s2, and md0s2a.
  5. Make temporary mount points in /tmp:
    # mkdir -p /tmp/1 /tmp/2
  6. Mount the MS-DOS boot partition /dev/md0s1
    # mount -t msdosfs /dev/md0s1 /tmp/1 
  7. Mount the FreeBSD UFS partition md2s2a
    # mount -t ufs /dev/md0s2a /tmp/2
  8. Edit config.txt in /mnt/1/config.txt to enable the USB keyboard. The following is based on config_rpi4.txt that works for me.
    [all]
    init_uart_clock=3000000
    enable_uart=1
    kernel=u-boot.bin
    kernel7=u-boot.bin
    dtoverlay=mmc
    dtoverlay=dwc2,dr_mode=host
    hdmi_safe=1
    armstub=armstub8-gic.bin
    arm_64bit=1
    dtoverlay=disable-bt
    device_tree_address=0x4000
    
  9. Add the following to /tmp/2/etc/rc.conf
    devmatch_enable="NO"
  10. Copy the rpi-firmware files onto the MS-DOS partition.
    # cd /tmp/1
    # cp -r /usr/local/share/rpi-firmware/* .
    
  11. Unmount and detach the modified image.
    # cd ..
    # umount /tmp/1 /tmp/2 
    # mdconfig -d -u 0
    
  12. Transfer the modified image to a Mac and use the RPI Imager to write it to the SD card (or eMMC if mounting the module with usbboot). Use the menu option "Operating System → Use Custom" in RPI Imager.

References