FreeBSD-based Raspberry Pi (3 or 4) image, built using poudriere.
Largely inspired by NanoBSD-embedded.
Poudriere will create an arm64.aarch64 base jail which will be used to compile the ports listed in pkglist. Then, it will create an image using the base jail and the ports.
There are two possible image versions, ZFS or UFS-based. As much as we like ZFS, we have observed that UFS performs a little better on the Pi as the base system.
The upgrade process for ZFS is a new boot environment, while for UFS is a ping-pong deployment on a specific partition. ZFS's boot environments can be kept as needed, as long as the current version supports them.
The system is mounted read-only to preserve the life of the SD card or EEPROM (in the case of a compute module).
As a recommended best practice, we currently keep the base system with a UFS file system, and external drives with ZFS (similar to schenkeveld10).
-
Create a poudriere jail with a
GENERIC-MMCCAM-NODEBUGkernelpoudriere jail -c -j rpi -a arm64.aarch64 -m git+https -v main -K GENERIC-MMCCAM-NODEBUG -
Create a ports tree
poudriere ports -c -U https://git.freebsd.org/ports.git -B main -p latest -
Create/modify the list of ports to be included
cat > pkglist <<EOF editors/vim lang/python security/sudo ... EOF -
Build the ports
poudriere bulk -j rpi -b latest -p latest -f pkglist -
Create the image
poudriere image -t firmware -j rpi -s 10g -p latest -h raspberrypi -n raspberrypi \ -f pkglist -c overlaydir -B pre-script-ufs.shIf ZFS is desired
poudriere image -t zfs -j rpi -s 5g -p latest -h raspberrypi -n raspberrypi \ -f pkglist -c overlaydir -B pre-script-zfs.sh -
Optionally, test the image
qemu-system-aarch64 -m 4096M -cpu cortex-a72 -M virt \ -bios /usr/local/share/u-boot/u-boot-qemu-arm64/u-boot.bin \ -serial telnet::4444,server -nographic \ -drive if=none,file=/usr/local/poudriere/data/images/raspberrypi.img,id=hd0 \ -device virtio-blk-device,drive=hd0 -
Copy the image to the SD card
dd if=/usr/local/poudriere/data/images/raspberrypi.img \ of=/dev/da0 bs=4M conv=fsync status=progress
-
Update the poudriere jail
poudriere jail -u -j rpi -
Update the ports tree
poudriere ports -u -p latest -
Build the ports
poudriere bulk -j rpi -b latest -p latest -f pkglist -
Create a boot environment (BE)
poudriere image -t zfs+send+be -j rpi -s 5g -p latest -h raspberrypi -n raspberrypi \ -f pkglist -c overlaydir -B pre-script-zfs.sh -
Test the BE image:
-
Optionally, compress the BE image created in the previous step
xz -9 --keep /usr/local/poudriere/data/images/raspberrypi.be.zfs -
Start a VM with the old image
qemu-system-aarch64 -m 4096M -cpu cortex-a72 -M virt \ -bios /usr/local/share/u-boot/u-boot-qemu-arm64/u-boot.bin \ -serial telnet::4444,server -nographic \ -drive if=none,file=/usr/local/poudriere/data/images/raspberrypi.img,id=hd0 \ -device virtio-blk-device,drive=hd0 -
From the Raspberry Pi, import the new BE
fetch -o - https://srv/raspberrypi.be.zfs.xz | unxz | bectl import newbe -
Boot once
bectl activate -t newbe -
Reboot
shutdown -r now "Rebooting for a firmware upgrade"
-
In order to save configuration changes, issue the following command:
# save_cfg
Configuration (/etc and /usr/local/etc) changes will be saved to /cfg (and /cfg/local).
- Adapt NanoBSD's update scripts
- UFS (Files-UFS)
- ZFS (Files-ZFS)
- Test gunion(8)
/cfg(unionfs works, but...) - Incremental ZFS snapshots
- Clean-up pre-scripts
- Improve sample directories and pkglist
- Improve documentation