FreeBSD on NanoPi R2S

The NanoPi R2S is a nice little ARM board that can serve nicely as a home router or firewall. It is comparable in power to a RaspberrryPi 3 with a 4 cores ARM Cortex-A53 SoC, namely the Rockchip RK3328. It has no video or sound output, only a handful GPIOs compared to a RPi, but it has one great advantage. It has 2 Ethernet ports, one of them is a true Gigabit internal card and the second is also a Gigabit connected through the internal USB3, so it’s a bit slower. On the RPi3, if you want 2 Gigabit Ethernet ports, you need an external card and both ports would run on the USB3, drastically limiting the bandwidth.

They generally come with a heatsink and a fan integrated as the board is quite small compared to a RPi and heats up more easily. People generally use this board with OpenWrt or Ubuntu. In the past, I also used it with Armbian as my home network gateway. People also managed to run it on OpenBSD. But this post focuses on FreeBSD.

ARM64 has been a tier-1 architecture on FreeBSD for more than a year now, which I discussed in this post. I managed to run the RPi 2B+, 3 and 4 easily, but my attempts with the Nanopi R2S proved rather unsuccessful and had their fair share of kernel panics.

Fast forward one year, and we are now at FreeBSD 13.1-p1. So I recently gave it another try, and not only is the whole experience much more stable, the installing process is also much easier and straightforward.

Installation

To install FreeBSD, I used the image provided at PersonalBSD. It’s a custom image based on a patched version of FreeBSD 13. It’s quite customized in fact, and point to its own repo by default. It starts sshd by default, and run both interfaces on DHCP. It has pubkey root login enabled and also has another admin user installed.

The rc.conf has growfs enabled, so the first boot will grow the ROOT UFS partition to the size of your SD card. It’s all GPT. There is a 256MB swap partition, but you can add a file based swap if you want. For instance in /etc/fstab:

md99 none swap sw,file=/.swap,late 0 0

The root partition has the following options enabled:

tunefs: POSIX.1e ACLs: (-a)                                disabled
tunefs: NFSv4 ACLs: (-N)                                   disabled
tunefs: MAC multilabel: (-l)                               disabled
tunefs: soft updates: (-n)                                 disabled
tunefs: soft update journaling: (-j)                       disabled
tunefs: gjournal: (-J)                                     disabled
tunefs: trim: (-t)                                         disabled
tunefs: maximum blocks per file in a cylinder group: (-e)  4096
tunefs: average file size: (-f)                            16384
tunefs: average number of files in a directory: (-s)       64
tunefs: minimum percentage of free space: (-m)             8%
tunefs: space to hold for metadata blocks: (-k)            2768
tunefs: optimization preference: (-o)                      space

It has soft updates disabled, which means that if the board has a hard reboot, you are in for some fsck nightmare. You can enable softupdates offline when the card is connected to your computer (running FreeBSD) for instance:

tunefs -n /dev/da0p2

I highly recommend to enable soft updates to save you much hassle.

Playing around

By default there is no EEPROM for the MAC addresses so they are randomly generated on each boot. Keep this in mind if you want to use IPv6 and SLAAC. There is also three status LEDs on the board. You can control them from the command line with echo 0|1 > /dev/led/nanopi-r2s:*. The custom image comes with a daemon and rc.local shell lines to setup a default state for the LEDs, but you can easily disable it.

The two interfaces are dwc0 for the Rockchip internal card, and ue0 for the card connected through USB3. Here is a quick test with iperf3 using UDP on both interfaces. Results are given in Mbits/sec.

TX RX
dwc0 765 946
ue0 784 370

 

Running it

But does it fit an use for a full fledged Internet gateway? I ran the Nanopi R2S for some time now as a home network gateway, and while it worked very well most of the time, the R2S would from time to time become completely inaccessible. Although it did not seem to panic as scripts where still running behind the scene. I could not identify what the problem was, but I know that the problem happened when either the Ethernet cable on the LAN interface was disconnected, or when too much traffic arrived on the Ethernet port.