Keeping FreeBSD up-to-date on Raspi-B from Linux (#100DaysToOffload Day31)

So if you follow my blog/fediverse account you know that i've started using FreeBSD on some RapberryPi Model B's i had around(that's down to 1 now...) as some in home servers. The remaining one hosts my gopher space and a disposable mailbox service. The trouble I've had was that the only way to upgrade between releases was to either build from source on the Pi(haha who's got time for that) or start from scratch with a new image every time. Had to come up/find another option.

Thanks to @mpts@mastodon.social who pointed me to an article about just this. Mind you the article is about FreeBSD 11 but same process applies. So i set off to get this going. First attempt was to do it from my little Dell laptop. While it worked it took like 2 and a half hours to build world+kernel. Had to be a faster way. Not that this needs to be done often but still. Then it hit me. I can use Qemu on my linux PC to setup and use FreeBSD. So i did just that. This post will detail the steps i took to get this accomplished. The time savings are well worth it in my case. So lets get started.

Step 1 is to create the disk image. This is done like so

qemu-img create -f qcow2 -o preallocation=full FreeBSD.img 64G

Since i only plan on using this to build for the Raspberry Pi 64gb should be more than enough. Preallocation will speed things up a little by having the file at it's max size and not having it take time to expand as it needs.

Step 2 is to grab the 64-bit installer image for FreeBSD 12.2 and use that to install FreeBSD in our VM.

We start Qemu like so to boot the installer.

qemu-system-x86_64 -vga std -smp cores=8 -machine accel=kvm -m 4096 -hda FreeBSD.img -cdrom FreeBSD-12.2-RELEASE-amd64-disc1.iso -name "FreeBSD" -rtc base=localtime -boot d

This will create/boot a VM with 8 processors/cores and 4g of ram using our image created above as the hard disk. We can then step through the installation as normal. The defaults are good enough for this use.

After the install is finished we can power down the VM and start it back up without the cd mounted like so

 qemu-system-x86_64 -vga std -smp cores=8 -machine accel=kvm -m 4096 -hda FreeBSD.img -name "FreeBSD" -rtc base=localtime 

The rest of this is taken directly from the article linked above and adapted to build 12.2 instead of 11.

So Step 3 is to grab the FreeBSD source.

cd /usr/src
svn checkout https://svn.freebsd.org/base/releng/12.2

Once this has completed we can start the build

make -j9 TARGET_ARCH=armv6 UBLDR_LOADADDR=0x2000000 buildworld

It is important to set the UBLDR_LOADADDR variable otherwise the system wont boot.

On my system this took about about 30 minutes.

Once that is down we build the kernel

make -j9 TARGET_ARCH=armv6 KERNCONF=RPI-B buildkernel

This took about 5 minutes for me.

Now came the next part i knew i would have to figure out. How to mount the Pi's SD card in Qemu. After some searching i found how to do this using USB pass-throught. First step is to find the device by using lsusb

Bus 004 Device 003: ID 0480:0212 Toshiba America Inc External USB 3.0
Bus 004 Device 002: ID 0480:0212 Toshiba America Inc External USB 3.0
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 1058:1230 Western Digital Technologies, Inc. My Book (WDBFJK)
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 17f6:0821 Unicomp, Inc R6_0_Trackball_v3_45
Bus 001 Device 002: ID 046d:c52b Logitech, Inc. Unifying Receiver
Bus 001 Device 009: ID **1908:0226** GEMBIRD 
Bus 001 Device 004: ID 1058:0827 Western Digital Technologies, Inc. My Passport 0827
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Note the bolded vendor/product ID above. The resulting command is then

qemu-system-x86_64 -vga cirrus -smp cores=8 -machine accel=kvm -m 4096 -hda FreeBSD.img -device usb-ehci,id=ehci -device usb-host,bus=ehci.0,vendorid=0x**1908**,productid=0x**0226** -name "FreeBSD" -rtc base=localtime

Notice the same bolded vendor/product id's. This will allow access to that USB device from the FreeBSD VM just as if it was connected to a physical pc.

Now we keep going with the install of the kernel/world we just built.

First we mount the SD card

mount /dev/da0s2a /mnt

Device name might differ.

Then the install steps

make TARGET_ARCH=armv6 KERNCONF=RPI-B DESTDIR=/mnt installkernel
mergemaster -p -A armv6 -D /mnt
make TARGET_ARCH=armv6 DESTDIR=/mnt installworld
mergemaster -iF -A armv6 -D /mnt
make TARGET_ARCH=armv6 DESTDIR=/mnt delete-old
make TARGET_ARCH=armv6 DESTDIR=/mnt delete-old-libs

This takes very little time overall. The biggests steps in a way are the 2 mergemaster commands as you have to pay attention to the files so you don't wipe your configurations.

Once that is all done we simply unmount the SD card, put it in the Pi and power it on. If all went well we should have a Pi booted up with the latest release of FreeBSD-12.2.

That's all for now.

Until next time. Be Safe!

@mgrondin@youdabomb.social

#Tech #FreeBSD