Table of Contents

Nov 21, 2022

Messing with Rock 5B

Front note: this is a non-exhaustive blog post about my Rock 5B experience. Stay tuned for more.

RK 3588 was really hyped among our Linux User Group: ARM single-board SoC that outperforms Raspberry Pi's, and mainline Linux kernel support in the near future. One of my friend happens to have an unused coupon, and I got hands on Radxa Rock 5B 8GB model for just ¥678.


(this is not mine; mine is already deployed to our studio's "datacentre"; exactly the same spec though)

Rock in rack

(this is mine)


While being much more powerful, the Rock 5B is noticably larger than Raspberry Pi 4B. The larger size also provides more room for I/O ports. On one side it has a 3.5mm headphone jack, 2 HDMI capable of 8K output (more of a gimmick in my opinion), 2 USB 2.0, 2 USB 3.0, and a 2.5 GbE port. On the other side are GPIO pins and an HDMI input port. On the board it has a M.2 slot for networking, an M.2 and eMMC extension slots for storage. This board is packed with extensibility.

I bought an 1 TB Hikvision CC 300 SSD for (overkilled) storage, and hopefully I can deploy a Git server or some sort of personal services. (which is a bad idea, I know, right?) I didn't bundle my Rock with eMMC modules, and used more versatile micro SD card instead. (this is not needed if you have other storage; see below)

Power supply also needs some consideration. Its website says it supports PD 2.0 with 12V / 15V / 20V voltage and 2A current. I just bought some random 30 W PD charger and it works like a charm.

Trying Linux (and Docker)

While 3rd-party OS ports exist, Radxa only provides 3 official images as of now: Android 12, Debian 11 with Xfce and Ubuntu Server 20.04. I don't have any plans to use Android, so I flashed Debian first.

The problem appears when I tried to install Docker. It just refused to work whenever I tried to install it via its official APT repository. It appears that systemd won't start docker.service, and I have no idea what was going on. journalctl -xe only said "start request repeated too quickly".

*** Not my log, but my log looks similar to this ***

Jul 26 15:52:00 VM-BLUBU16CSS systemd[1]: Listening on Docker Socket for the API.
-- Subject: Unit docker.socket has finished start-up
-- Defined-By: systemd
-- Support:
-- Unit docker.socket has finished starting up.
-- The start-up result is done.
Jul 26 15:52:00 VM-BLUBU16CSS systemd[1]: docker.service: Start request repeated too quickly.
Jul 26 15:52:00 VM-BLUBU16CSS systemd[1]: Failed to start Docker Application Container Engine.
-- Subject: Unit docker.service has failed
-- Defined-By: systemd
-- Support:
-- Unit docker.service has failed.
-- The result is failed.
Jul 26 15:52:00 VM-BLUBU16CSS systemd[1]: docker.socket: Unit entered failed state.

I removed Xfce and other GUI-related packages the day before that, so maybe it's myself to blame. After trying workarounds on the Internet one by one and failing, I was bored and decided to move to Ubuntu. Its image is much smaller (~250 MB vs Debian's ~700 MB) and does not include GUI, which I don't need. Installing Docker on Ubuntu was a breeze, and I am sticking to it.


Note that kernel version: Ubuntu 20.04 LTS comes with Linux kernel 5.4, but here we are using Rockchip's custom-built Linux 5.10.

3rd-party Armbian does exist, but PD charger is broken on it (PD protocol is handled in kernel), and a fixed-voltage adapter has to be used, making this distro a no to me.

Installing Linux on NVMe SSD

In the above section, I tried Linux on my 64 GB micro SD card. Now it's time to flash Linux to my overkill SSD!

Flashing Linux into SSD can be easily done on Rock 5B itself. Download the image, decompress it and pipe it to the device:

$ xzcat <your compressed image path> | \
  sudo dd of=<your NVMe SSD device path> bs=1M status=progress

# or the more risky one-liner

$ curl <image URL> | xzcat | \
  sudo dd of=<your NVMe SSD device path> bs=1M status=progress

According to Radxa wiki, to install Linux on NVMe drive and boot it, you also need to flash U-Boot image to SPI NOR Flash. But without this step, the board boot unexpectedly into NVMe SSD with my SD card attached. My guess is that U-Boot inside the SD card chooses kernel on the SSD rather than the SD card one, but this is yet to be verified.

Following the wiki and flashed SPI using rkdeveloptool, I can safely bid farewell to that SD card and use SSD entirely.

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            3.7G  8.0K  3.7G   1% /dev
tmpfs           770M  528K  769M   1% /run
/dev/nvme0n1p2  954G   17G  900G   2% /
tmpfs           3.8G     0  3.8G   0% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           3.8G     0  3.8G   0% /sys/fs/cgroup
/dev/nvme0n1p1  511M   67M  445M  13% /boot
tmpfs           770M  4.0K  770M   1% /run/user/1001

WireGuard and DKMS Hacking

WireGuard is such an easy way of connecting devices, and it has kernel-level support since Linux 5.6, thus should work out of the box if we have 5.10 already. But when I installed wireguard and tried to add an WireGuard interface:

$ sudo ip link add wg0 type wireguard
Error: Unknown device type.

Weird, right? I removed and installed it again, and noticed that installing wireguard also have linux-headers-5.4* installed, which is confusing, since I already have Linux headers for the custom kernel installed.

It turned out that debian/control file from linux-headers-5.10.66-27-rockchip-gea60d38 does not Provide: linux-headers. I haven't found Radxa's APT manifest/manifest generator repository, so I may have to write a feedback and let them fix that.

My best guess is that Radxa or Rockchip simply disables WireGuard kernel module for some reason. However there's no sign of WireGuard removal in their kernel repositories. WireGuard DKMS for older versions of Linux should work anyway, so no reason should I not give it a try.

I noticed that wireguard-dkms was not being built in APT post-install hook:

Error! The dkms.conf for this module includes a BUILD_EXCLUSIVE directive which
does not match this kernel/arch. This indicates that it should not be built.

Manually building using dkms build wireguard/<version> resulted in the same error. This is normally not an issue because dkms.conf file excluded Linux 5.51 or above that has built-in WireGuard support. Now I just needed to bypass it.

wireguard-dkms is an Architecture: all package that contains WireGuard DKMS' source code. The code is not being built when packaging, but during installation. I re-packaged wireguard-dkms with my patch to disable Linux version check, both in dkms.conf and its source code:

$ cat debian/patches/0003-Remove-kernel-version-check-for-rockchip.patch 
--- a/src/compat/compat.h
+++ b/src/compat/compat.h
@@ -42,9 +42,9 @@
#error "WireGuard requires Linux >= 3.10"

-#error "WireGuard has been merged into Linux >= 5.6 and therefore this compatibility module is no longer required."
+// #error "WireGuard has been merged into Linux >= 5.6 and therefore this compatibility module is no longer required."
+// #endif

#if defined(ISRHEL7)
#include <linux/skbuff.h>
--- a/src/dkms.conf
+++ b/src/dkms.conf
@@ -6,10 +6,10 @@

-if ls /lib/modules/5.5*/source/include/uapi/linux/wireguard.h >/dev/null 2>&1 ; then
-    # debian backported wireguard into the 5.5 release:
-    BUILD_EXCLUSIVE_KERNEL="^((5\.[0-4]($|[.-]))|(4\.)|(3\.1[0-9]))"
-    # upstream requires kernel 3.10 - 5.5, inclusive:
-    BUILD_EXCLUSIVE_KERNEL="^((5\.[0-5]($|[.-]))|(4\.)|(3\.1[0-9]))"
+# if ls /lib/modules/5.5*/source/include/uapi/linux/wireguard.h >/dev/null 2>&1 ; then
+#     # debian backported wireguard into the 5.5 release:
+#     BUILD_EXCLUSIVE_KERNEL="^((5\.[0-4]($|[.-]))|(4\.)|(3\.1[0-9]))"
+# else
+#     # upstream requires kernel 3.10 - 5.5, inclusive:
+#     BUILD_EXCLUSIVE_KERNEL="^((5\.[0-5]($|[.-]))|(4\.)|(3\.1[0-9]))"
+# fi

After replacing wireguard-dkms with my freshly-patched-and-packaged one, voila! I was finally able to set up my WireGuard interface:

$ sudo wg
interface: wg0
  public key: Y+OVVBid/rYTDfvphdmLXceBhZ0I2/XyCCZKHHaU2UE=
  private key: (hidden)
  listening port: 51820

peer: Z1Dp+WGZxhRwO8qdAPTPJGbamKY6gPqpTPCR0UstmTM=
  endpoint: -snip-
  allowed ips:
  latest handshake: 2 days, 5 hours, 35 minutes, 33 seconds ago
  transfer: 38.10 KiB received, 42.04 KiB sent

Here I want to mention Armbian again, since it is said that WireGuard works out-of-the-box. I cannot test it due to aforementioned issue, sorry.


Debian backported WireGuard support to Linux 5.5.

arrow_back_ios_new Next
Prev arrow_forward_ios