RISC-V small computer

For a long time I’ve wanted something Raspberry-pi-like but with RISC-V. And finally there is one, and a defensible price! Especially with the Raspberry Pi 4 shortage this seemed like a good idea.

This post is my first impressions and setup steps.

It’s just like when I was a kid!

When I was in my late teens I was playing with different architectures, mostly using discarded university computers. It was fun to have such different types of computers. Back then it was SPARC (And UltraSparc), Alpha, and x86. Maybe access to some HPPA. I even had a MIPS (SGI Indigo 2).

Nowadays instead of SPARC, Alpha, and x86 it’s ARM, RISC-V, and x64.

Luckily they can be smaller nowadays. Before I left home my room had more towers of computers than it had furniture. In my first flat I had a full size rack!

Write SD card

sudo dd if=starfive-jh7110-VF2_515_v2.5.0-69-minimal-desktop.img \
   of=/dev/sda bs=4M status=progress conv=fdatasync

Repartition SD card

We need to repartition, because the boot partition is way too small. It only fits one kernel/initrd, which became a problem I ran into.

Unfortunately gparted doesn’t seem to work on disk images. It wants access to the individual partitions. I’m sure I could mess with partitioned loop devices, but it tends to get messy. So I just worked against the SD card directly.

  1. gparted /dev/sda
  2. Move /dev/sda3 (root) one gig to the right.
  3. Expand /dev/sda2 (boot) to fill the new space.
  4. Click green button to apply, and wait.

Resizing vfat (boot filesystem) apparently doesn’t work, so we’ll have to do that manually.

sudo mount /dev/sda2 /mnt/tmp
cd /mnt/tmp
tar cf ~/tmp/bo.tar .
cd ~/tmp
umount /mnt/tmp
sudo mkfs.vfat -F 16 /dev/sda2
sudo mount /dev/sda2 /mnt/tmp
cd /mnt/tmp
sudo tar xf ~/tmp/bo.tar
cd
sudo umount /mnt/tmp
sync

I tried fatresize -s max /dev/sda2, but it didn’t seem to actually do anything.

Maybe I don’t actually need a gig for /boot, once the correct kernel upgrades happen (see below), but 100MB is too small.

Boot up

I’m connected on console using the same cable I use for Raspberry Pi console access. Just make sure to not connect the 5V lead. Only ground, RX, and TX. Just like with Raspberry Pi.

Login as root / starfive.

I add a user, enable sudo for that user, and SSH in.

adduser thomas
echo 'thomas ALL=(ALL) NOPASSWD: ALL' > /dev/sudoers.d/thomas

Seems the hostname is not in /etc/hosts, so I added it there to remove warnings.

I also have an HDMI video capture device, something like this one, and interestingly even the minimal image seems to have an X server.

It seems that the best way to get clean low latency output from this capture card is:

cvlc v4l2:///dev/video4:chroma=mjpg --live-caching=0

Upgrade firmware

In a link on the forum I found on reddit it says that I should update SPL and U-Boot. So let’s do that.

flashcp -v u-boot-spl.bin.normal.out /dev/mtd0
flashcp -v visionfive2_fw_payload.img /dev/mtd1

Running

$ cat /proc/cpuinfo
processor       : 0
hart            : 1
isa             : rv64imafdc
mmu             : sv39
uarch           : sifive,u74-mc

processor       : 1
hart            : 2
isa             : rv64imafdc
mmu             : sv39
uarch           : sifive,u74-mc

processor       : 2
hart            : 3
isa             : rv64imafdc
mmu             : sv39
uarch           : sifive,u74-mc

processor       : 3
hart            : 4
isa             : rv64imafdc
mmu             : sv39
uarch           : sifive,u74-mc
$ free -m
               total        used        free      shared  buff/cache   available
Mem:            7927         326        7078           6         522        7509
Swap:              0           0           0

I built some stuff in Go, C, C++, and Rust. It seems to “just work”. It’s a Linux system, I know this.

Wireguard and the kernel

This is where I ran into trouble my first attempt, since apt install wireguard will install a new kernel into /boot, which won’t fit.

It also seems to use the wrong directory structure. The original kernel (5.15.0) is in /boot/boot/ for some reason, but the new kernel (5.18.0) gets put into /boot.

It’s also not compressed, for some reason, and the initrd is huge!

-rwxr-xr-x 1 root root 7.7M Dec 21 08:56 /boot/boot/vmlinuz-5.15.0-starfive
-rwxr-xr-x 1 root root  20M Jun  6  2022 /boot/vmlinux-5.18.0-1-riscv64
-rwxr-xr-x 1 root root 9.3M Dec 21 09:31 /boot/boot/initrd.img-5.15.0-starfive
-rwxr-xr-x 1 root root  60M Jan 25 19:38 /boot/initrd.img-5.18.0-1-riscv64

Maybe I should just stay clear of that kernel, if it’s not customized for starfive? Will it boot? Not tried yet.

The default kernel does not support wireguard:

$ sudo wg-quick up ./foowg.conf
[#] ip link add foowg type wireguard
Error: Unknown device type.
Unable to access interface: Protocol not supported
[#] ip link delete dev foowg
Cannot find device "foowg"

There are other things annoyingly missing from the dist kernel:

  • IPv6
  • BPF
  • IPSec
  • MD5SIG
  • Bridging
  • AX.25
  • MD (RAID)
  • PPP / SLIP
  • BtrFS
  • iso9660 (CD-ROM)
  • TLS

Weird things

There’s stuff in /usr/local/, including an old version of openssl? Wat? That doesn’t seem right. Let’s just move that out of the way:

mv /usr/local{,.orig}
mkdir /usr/local

Future

I have an M.2 NVMe drive on the way, that aside from much more space, will also presumably be faster and more reliable.

The USB wifi dongle that came with the sifive doesn’t seem to be detected. Maybe I need to install some driver.

There’s plenty of benchmarking and such left to do, as well. But before I do that maybe I’ll need active cooling? I should read up on this.

So far though I can say that it’s fast enough for lab purposes. I don’t really care if it’s the best processing per watt. That’s not what it’s for, for me. But I would be disappointed if it were annoyingly slow to use. It’s not.

It doesn’t have AES instructions, so be deliberate in how you compare this benchmark to anything, but here’s openssl speed:

Doing sha256 for 3s on 16 size blocks: 843430 sha256's in 3.00s
Doing sha256 for 3s on 64 size blocks: 561138 sha256's in 2.99s
Doing sha256 for 3s on 256 size blocks: 279993 sha256's in 3.00s
Doing sha256 for 3s on 1024 size blocks: 93370 sha256's in 3.00s
Doing sha256 for 3s on 8192 size blocks: 12927 sha256's in 3.00s
Doing sha256 for 3s on 16384 size blocks: 6490 sha256's in 2.99s
Doing sha512 for 3s on 16 size blocks: 822824 sha512's in 3.00s
Doing sha512 for 3s on 64 size blocks: 820624 sha512's in 3.00s
Doing sha512 for 3s on 256 size blocks: 398446 sha512's in 2.99s
Doing sha512 for 3s on 1024 size blocks: 155672 sha512's in 3.00s
Doing sha512 for 3s on 8192 size blocks: 23303 sha512's in 3.00s
Doing sha512 for 3s on 16384 size blocks: 11786 sha512's in 3.00s
Doing aes-256-cbc for 3s on 16 size blocks: 3385626 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 64 size blocks: 1054135 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 256 size blocks: 281246 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 1024 size blocks: 71503 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 8192 size blocks: 8980 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 16384 size blocks: 4487 aes-256-cbc's in 3.00s

It has four cores, and each core then seems approximately one tenth the speed of a core on my laptop on SHA. Not bad. Don’t know if the above thermothrottled, though.

For future RISC-V hardware I’m looking forward to playing with the vector instructions. They are more truly different than the rest of the instruction set.