Running gokrazy on a Banana Pi BPI-R1
CLI . Go . Hacking . TestingI had a BPI-R1 sitting in a drawer. The board is from 2014 — only ancient OpenWrt and outdated Armbian images exist for it. Nobody maintains this platform anymore.
The hardware is fine though: dual-core Allwinner A20, 1GB RAM, SATA, and a BCM53125 5-port Gigabit switch on the board. Not bad for a dedicated network appliance.
I’m a Go fan, and I knew about gokrazy — pure Go userland, squashfs root, no package manager. The BPI-R1 wasn’t supported. So I added it.
The Board
The BPI-R1 (aka “Lamobo R1”) runs an Allwinner A20 SoC — dual Cortex-A7 @ 1GHz, ARMv7, 32-bit. The standout feature is the BCM53125 switch with four LAN ports and one WAN port, managed by Linux’s DSA framework. That switch caused most of the trouble.
Device Tree — The Source of Truth
When porting gokrazy to a new board, the Device Tree Source in the mainline kernel is your primary reference. For the BPI-R1: arch/arm/boot/dts/allwinner/sun7i-a20-lamobo-r1.dts.
This file tells you everything that matters:
- The model string is
"Lamobo R1"— not “Banana Pi R1”, not “BPI-R1”. gokrazy uses this string from/proc/device-tree/modelfor device identification. Wrong string = nothing works. - The Ethernet topology: DWMAC connected to BCM53125 via MDIO, five switch ports with their PHY addresses. This determines which kernel configs to enable.
- The serial console: UART0 on
ttyS0, pins PB22/PB23 on the J13 header. - The DTB filename:
sun7i-a20-lamobo-r1.dtb— one of the build artifacts for the kernel package.
I had an old Armbian snapshot to cross-reference, but the DTS source is authoritative. Marketing names and wiki pages will mislead you.
Kernel and U-Boot
gokrazy’s kernel packaging is convention-based: put vmlinuz, DTB, boot.scr, and u-boot-*.bin into a Go module, and the packer finds them. I used gokrazy-rock64-kernelas a template.
The build scripts download mainline Linux 6.12.23 and U-Boot 2025.04, cross-compile in Docker, and copy the artifacts out.
Kernel config
Base: sunxi_defconfig. Problem: it doesn’t include CONFIG_SQUASHFS. gokrazy needs squashfs for its root filesystem. Without it:
Kernel panic - VFS: Unable to mount root fs on "PARTUUID=..."
My config addendum adds ~175 options. The critical ones:
CONFIG_SQUASHFS=y— cost me an hour of debuggingCONFIG_VFAT_FS=y,CONFIG_NLS_*— FAT32 boot partitionCONFIG_NET_DSA=y,CONFIG_B53=y— BCM53125 switchCONFIG_RTL8XXXU=m,CONFIG_CFG80211=m,CONFIG_MAC80211=m— WiFi (the oldCONFIG_RTL8192CUstaging driver was removed in kernel 6.12)
U-Boot
Straightforward: Lamobo_R1_defconfig, output is u-boot-sunxi-with-spl.bin. 32-bit ARM boots with bootz (not booti). SPL goes to sector 16 on the SD card, MBR-only.
Device Config
gokrazy needs to know the U-Boot offset on the SD card. This goes into deviceconfig/config.go:
"Lamobo R1": {
MBROnlyWithoutGPT: true,
RootDeviceFiles: []RootFile{
{"u-boot-sunxi-with-spl.bin", 16 * sectorSize, 2032 * sectorSize},
},
BootPartitionStartLBA: 2048,
Slug: "bpi_r1",
},
I forked gokrazy/internal, added the config, and rebuilt gok with a local replacedirective. Works until the PR is merged.
Serial Console
Without serial, this project would not have worked.
gokrazy is headless — no SSH by default, no shell. On a new board port, the network doesn’t work yet. Serial is your only way in.
The BPI-R1 has a UART header (J13). USB-to-serial adapter,
screen /dev/tty.usbserial-111130 115200,cs8
on macOS.
Serial was essential at every stage:
- First boot: Seeing the exact kernel panic (
squashfs not compiled in) instead of just a board that doesn’t come up. - DSA debugging: Running
ip link showto discover all switch ports were down, thenip link set wan upandudhcpc -i wanto manually test DHCP. - Iteration loop: Flash card, boot, read serial, identify problem, fix, repeat. About a dozen cycles, 5 minutes each.
One quirk: gokrazy starts a busybox shell when it detects serial input. The first character triggers the shell and gets swallowed. Type ip link show too fast and you get p link show. Wait for the / # prompt.

DSA Networking
The board booted on the first try. But no network.
gokrazy’s DHCP client defaults to eth0. On the BPI-R1, eth0 is the DSA master interface — the CPU port of the switch. Traffic flows through the individual switch ports instead: lan1–lan4 and wan. All start DOWN.
3: eth0: ... state UP
4: lan2@eth0: ... state DOWN
7: wan@eth0: ... state DOWN
8: lan1@eth0: ... state DOWN
Fix: point DHCP at the port with the cable.
"PackageConfig": {
"github.com/gokrazy/gokrazy/cmd/dhcp": {
"CommandLineFlags": ["-interface=wan"]
}
}
The DHCP client calls LinkSetUp() on the target interface automatically. Port comes up, DHCP lease obtained, web interface reachable.
Result
The BPI-R1 boots gokrazy in ~6 seconds. 5-port switch works via DSA. Persistent storage on ext4. Hardware watchdog active. OTA updates and breakglass SSH both work over the network.
Still missing: WiFi firmware blobs and the upstream device config PR.
Takeaways
- Check what
defconfigactually includes.sunxi_defconfigis minimal. It doesn’t have squashfs, WiFi, or other things gokrazy needs. - DSA boards need per-port DHCP. The master interface isn’t where traffic flows.
- Read the DTS, not the wiki. The model string, peripheral wiring, and driver requirements are all in the Device Tree Source.
- Serial is non-negotiable for board bring-up. No serial, no debugging.
Code: consolving/gokrazy-kernel-a20 | consolving/gokrazy-internal (branch add-bpi-r1-device-config)
Related
Archives
- April 2026
- March 2026
- August 2025
- November 2023
- February 2023
- January 2023
- April 2020
- January 2018
- December 2017
- May 2017
- February 2016
- September 2015
- December 2014
- August 2014
- June 2014
- March 2014
- February 2014
- September 2013
- August 2013
- July 2013
- November 2012
- October 2012
- September 2012
- June 2012
- May 2012
- April 2012
- March 2012
- February 2012
- January 2012
- December 2011
- November 2011
- October 2011
- August 2011
- July 2011
- June 2011
- May 2011
- January 2011
- August 2010
- July 2010
- June 2010
- May 2010
- January 2010
- November 2009
- October 2009
- September 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- September 2006
- June 2006
- May 2006
- April 2006
- March 2006
- February 2006
- January 2006
Leave a Reply