julienblanchard.com $home

Setting up a 9front CPU server on a Raspberry Pi 4

2024-03-01 17:52:00

Recently got a Raspberry Pi 4 and I wanted to make it a 9front CPU server. I struggled a bit so here are some notes on what I did.

By default 9front image for Raspberry Pi is quite small around 2GB, I wanted it use my whole 64GB SD Card so I used qemu to boot a 9front terminal and cross-compile a custom Pi4 image with more storage.

Making a custom Pi image

Since my SD Card is 64GB, I first created a qemu image of 100GB just to be safe, most probably less space is needed.

λ qemu-img create -f qcow2 9front.qcow2.img 100G

Then started qemu to boot the 9front iso and the qemu image.

λ qemu-system-x86_64 -enable-kvm \
  -smp $(nproc) \
  -m $((4*1024)) \
  -cpu host \
  -M q35 \
  -cdrom /path/to/9front.amd64.iso \
  -net nic -net user,hostfwd=tcp::17007-:17007,hostfwd=tcp::17010-:17010,hostfwd=tcp::17019-:17019,hostfwd=tcp::17020-:17020,hostfwd=tcp::12564-:564,hostfwd=tcp::12567-:567 \
  -drive file=/path/to/9front.qcow2.img,media=disk,index=0,cache=writeback

Ports 564 and 567 are used by drawterm but I can bind them as a non-root user so I bind them to 12564/12567.

When rio is started I made the VM accessible with drawterm.

auth/factotum -g 'key proto=p9sk1 dom=plan9 user=glenda !password=glenda'
aux/listen1 -t tcp!*!rcpu /rc/bin/service/tcp17019 -R &
ip/ipconfig

Then I can use drawterm to connect to the VM

PASS=glenda drawterm -a 'tcp!localhost!12567' -s localhost -h localhost -u glenda

In order to make image size bigger I changed mb=1885 to mb=60000 in the %.pi3.img: section of /sys/lib/dist/mkfile. Now I could build the new ~64GB Pi4 image.

First got to the 9front source dir

cd /sys/src

Built the arm64 userspace

objtype=arm64
mk install

Built the 64-bit kernel for Raspberry Pi ¾, the build script expects both kernels to be present

cd /sys/src/9/bcm64
mk 'CONF=pi3' install
mk 'CONF=pi4' install

Built the bootable hjfs SD Card image for Raspberry Pi ¾

cd /sys/lib/dist
bind / /n/src9
mk /tmp/sdcard.pi3.img

I order to copy the image outside the qemu VM I used /mnt/term

cp /tmp/sdcard.pi3.img /mnt/term/tmp/sdcard.pi3.img

And finally wrote the new image to my SD Card.

dd if=/tmp/sdcard.pi3.img of=/dev/sdb bs=4M oflag=direct status=progress

Turning the Pi into a CPU server

The Pi booted in terminal mode. In order to have it boot in cpu mode I edited cmdline.txt (the plan9.ini equivalent for the Pi). First I mounted the dos partition.

9fs dos 

Optional: if it complains that no dos partition is found

bind -b '#S' /dev

Updated /n/dos/cmdline.txt adding nobootprompt (so that the Pi automatically boots into the fs), declaring where the nvram is, that the user is glenda and that this machine is a cpu server.

console=0 nobootprompt=local!/dev/sdN0/fs nvram=/dev/sdN0/nvram user=glenda service=cpu

Adding nvram after nobootprompt was important for some reason otherwise it wouldn’t be taken into account. It’s also mandatory to have all these settings on a single line.

Then I set networking up. To get the ethernet identifier:

ip/ipconfig
cat /net/ether0/addr

I edited /lib/ndb/local to declare my ipnet and sys, I use DHCP.

...
#
#  because the public demands the name localhost
#
ip=127.0.0.1 sys=localhost dom=localhost

auth=nein authdom=9front
ipnet=9front ip=192.168.1.0 ipmask=255.255.255.0
    ipgw=192.168.1.254
    dns=192.168.1.254
    auth=nein
    dnsdom=9front
    cpu=nein
    smtp=nein

sys=nein dom=9front ether=<the ethernet identifier>

One last change is giving a password to glenda in nvram and for the local user.

auth/keyfs
nvram=/dev/sdN0/nvram auth/wrkey
authid: glenda
authdom: 9front
secstore key: <press enter to skip>
password: <type your password>
confirm pasword: <retype your password>

auth/changeuser glenda
Password: <same as what's in nvram>
...

Rebooted with fshalt -r, I’m now greeted by the cpu prompt. I need to get the cpu server IP:

cpu% cat /net/ndb
...
ip=192.168.1.76 ipmask=255.255.255.0 ipgw=192.168.1.254
  sys=nein
  dns=192.168.1.254

And I can finally connect via drawterm to my new CPU server \o/

PASS=<glenda's password> drawterm -h 192.168.1.76 -a 192.168.1.76 -u glenda