Go(ing)krazy on a Raspberry Pi (Model B)

October 28, 2022 on Olivier's log

I had an old Raspberry Pi lying around and wanted to achieve something with it.

I had previously played with it (installed raspbian, dietpi; run some custom software), but everytime I felt overwhelmed by having to ssh into it to upgrade it manually and fear of losing all my work in case of a mistake.

I gave Ansible a try to manage it "like a pro", but it felt like I had to write a lot of code to get something working (a systemd service, a local pre-compilation and a remote deploy) in a declarative language unknown to me.

Discovering gokrazy

I stumbled upon gokrazy, which looked really nice:

https://gokrazy.org/

It is a very very reduced Linux distribution, with the following parts:

Everything can be configured and prepared on another computer and then sent (by writing a SD-Card or over the network) to the Pi.

The only drawback, was that gokrazy supported only Raspberry Pi 3 B or later (with a mainline Linux kernel, which those devices support).

Getting krazy

I had been overwhelmed by managing a Linux distribution manually, but found it appealling to try to get gokrazy working on my old Raspberry Pi...

Gokrazy is very flexible and allows you to specify the firmware and the kernel you want. So I looked at the official gokrazy firmware package (for the Pi 3 B) and found the similar files for my Pi. I wrapped those files in an easy-to-use go package.

Go package to provide raspberry firmware for gokrazy appliance

I then had to provide a Linux kernel. I simply downloaded the kernel provided by raspbian and tried booting it. Sure enough the Pi was able to boot, however the kernel was having issues with the filesystem.

Gokrazy wraps all its image in a SquashFS filesystem. Support for this filesystem wasn't enabled by the raspbian distribution. Hence to go further I had to compile the Linux kernel myself (which sounded quite daunting to be honest).

Cross-Compiling Linux

It was actually quite easy! Thanks to the documentation of Raspberry Pi:

https://www.raspberrypi.com/documentation/computers/linux_kernel.html#cross-compiling-the-kernel

After the first compilation, I adjusted the config to add support for SquashFS. The Pi finally started to boot...to have a kernel panic shortly after.

The messages were quite cryptic ("VFS: unable to mount root fs on unknown-block") and I initially thought, that I didn't compile the kernel correctly and that SquashFS wasn't working. However it turned out that I was using a SD-Card which didn't have enough space!

Pull Request to the gokrazy project, to fail with a helpful error message when using a small SD-Card

Enjoying

After that, I added the go packages that I wanted and since then my Raspberry Pi can be confidently updated, by running the following command from my laptop:

GOKRAZY_UPDATE=https://gokrazy:secret-password@gokrazy \
GOARCH=arm GOARM=6 $$(go env GOPATH)/bin/gokr-packer \
    -kernel_package=github.com/gokrazy-community/kernel-rpi-os-32/dist \
    -firmware_package=github.com/gokrazy-community/firmware-rpi/dist \
    -eeprom_package= \
    -serial_console=disabled \
    -tls=self-signed \
    code.pfad.fr/private-package/gokrazy-rpib/cmd/victoria-metrics \
    code.pfad.fr/private-package/gokrazy-rpib/cmd/pfadscraper \
    github.com/oliverpool/grafana-armv6 \
    tailscale.com/cmd/tailscaled \
    tailscale.com/cmd/tailscale

This runs surprisingly well on such on old SBC (512 MB of RAM and single core running at 700 MHz). I might write another {web,gem}log post about the packages that run on it (mostly home automation and data tracking).