Taking a RISC

As a result of the Chip Crisis getting hold of Raspberry Pi SBCs has been tricky for the last year or so. If you manage to find a retailer that has some in stock before they get cleaned out by the scalpers they come bundled with PSU, pre-installed SD card, case and HDMI adapters (I understand why, it makes them more attractive to the original target audience).

At the same time there has been a growing number of new SBCs based on the RISC-V architecture. RISC-V is an open CPU architecture and looking to try and compete with the close ARM architecture which is found just about everywhere (Phones, new Macs, Watches, Set Top boxes, …)

So it seamed like a good time to see what boards were available and have a play. I had a bit of a search, and found a Sipeed Nezha RV64 Development Board on Amazon. It has the same basic layout as a Pi, all the same ports (plus some extra), a Debian Linux variant to run on it, the only thing lacking is RAM at 1GB, but that should be enough to get started.

Single Board Computer

Having ordered one, the delivery date was for mid October, early November but it turned up the 3rd weekend in September.

Unboxing

We get a reasonably nice box which contains the following

  • Sipeed Nezha 64bit 1GB Development Board
  • 32gb SD card preloaded with Debain Linux
  • 2 USB-A to USB-C cables
  • USB to Serial break out cable
  • American style USB Power supply
  • 4 Stand off feet

I don’t think I’ll be making use of the USB PSU, unbranded Chinese PSUs like this have a bad reputation and I don’t fancy digging out my UK to US step down transformer. Luckily when the Postman delivered this he also delivered one of the new Google Chromecast HDs which came with a suitable PSU that I don’t need as the TV has a USB socket I can use with the Chromcast.

The USB-A to USB-C cables also look a little strange, the USB-A end has a purple insert, but doesn’t look to have the USB-3 extra tracks and the data tracks look really thin. I’ll give them a go to power the board, but will probably use one of my existing cables with the USB-C OTG port on the board when I get round to seeing if I can drive it as a USB Gadget like I’ve been doing with Raspberry Pi 4 and Pi Zero boards.

I can’t find a matching case for this board online, while it’s mainly laid out like a Pi, the ports are not quite the same, so most Pi cases would need modifying. I may see if I can find somebody with a 3D printer to run one up for me. In the mean time I’ve screwed in the stand off feet to hold it up off the desk.

Powering up

As the board only has one USB-A socket I stuck a wireless keyboard/mouse dongle in to get started, along with a HDMI cable, ethernet and power.

When I plugged the power in I got absolutely nothing out to the display, but the power LED lit up and the link and data lights on the ethernet socket started to flash. I had a quick look in the DHCP table on my router and found a new device with a hostname of sipeed. I fired up SSH to connect as the sipeed user and entered the password printed on the inside of the box.

This got me logged into a bash shell. I found a shell script in the home directory called test_lcd.sh which when I examined hinted that i might be able to switch between a built in LCD driver and the HDMI output. Running the script at root with the argument of hdmi kicked the hooked up display into life.

X Windows running on half a screen

I appears (after a little searching) that the default X config is for a tablet sized screen in portrait mode, which is why it’s only using the left 3rd of the screen.

I’ll try and find some time to set up the display properly later, but for now we’ve proved nothing is broken.

Next I tried checking for any OS updates with sudo apt-get update but it threw errors to do with missing GPG keys.

root@sipeed:~# apt-get update
Get:1 http://ftp.ports.debian.org/debian-ports sid InRelease [69.6 kB]
Err:1 http://ftp.ports.debian.org/debian-ports sid InRelease
  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E852514F5DF312F6
Fetched 69.6 kB in 2s (34.0 kB/s)
Reading package lists... Done
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://ftp.ports.debian.org/debian-ports sid InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E852514F5DF312F6
W: Failed to fetch http://ftp.ports.debian.org/debian-ports/dists/sid/InRelease  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E852514F5DF312F6
W: Some index files failed to download. They have been ignored, or old ones used instead.

I’m pretty sure I can import them, just need to find the right key server to pull them from.

(From Redit)

$ busybox wget -O- https://www.ports.debian.org/archive_2022.key | apt-key add

Once I get the updates installed I’ll see if I can get NodeJS and give Node-RED and FlowForge a go.

That’s a basic sniff done. Will post some more when I’ve had time to poke round some more.

I’ve found some Fedora images for this board, here that I’ll probably boot up next, then give Ubuntu a go from here.

Full NGINX Logging Example

In a previous post I talked about how to setup NGINX to log both the request and response headers and bodies to help with debugging. It’s a lot easier to set up a HTTP reverse proxy than sort out all the private keys when trying to capture HTTPS with wireshark.

I needed to use that again recently and it took me a little while to remember exactly how to put it all together again, so this is just a really short follow up post with a full minimal example of the nginx.conf file needed.

worker_processes 1;
load_module modules/ndk_http_module.so;
load_module modules/ngx_http_lua_module.so;
pcre_jit on;

events {
  worker_connections 1024;
}

error_log /dev/stderr;

http {
  log_format log_req_resp '$remote_addr - $remote_user [$time_local] '
  '"$request" $status $body_bytes_sent '
  '"$http_referer" "$http_user_agent" $request_time req_body:"$request_body" resp_body:"$resp_body" '
  'req_headers:"$req_header" resp_headers:"$resp_header"';

  server {
    listen 80;
    access_log /dev/stdout log_req_resp;

    root /var/www/html;

    lua_need_request_body on;

    set $resp_body "";
    body_filter_by_lua '
      local resp_body = string.sub(ngx.arg[1], 1, 1000)
      ngx.ctx.buffered = (ngx.ctx.buffered or "") .. resp_body
      if ngx.arg[2] then
        ngx.var.resp_body = ngx.ctx.buffered
      end
    ';

    set $req_header "";
    set $resp_header "";
    header_filter_by_lua '
      local h = ngx.req.get_headers()
      for k, v in pairs(h) do
        if (type(v) == "table") then
          ngx.var.req_header = ngx.var.req_header .. k.."="..table.concat(v,",").." "
        else
          ngx.var.req_header = ngx.var.req_header .. k.."="..v.." "
        end
      end
      local rh = ngx.resp.get_headers()
      for k, v in pairs(rh) do
        ngx.var.resp_header = ngx.var.resp_header .. k.."="..v.." "
      end
      ';

  }
}

It also has a small improvement to allow for duplicate HTTP headers in the request (which is in spec). It will now concatenate the values in to a comma separated list.

This is intended to be used with the following Docker container (the default nginx container doe not have the lua module installed)

FROM debian:latest

RUN apt-get update && apt-get install -y libnginx-mod-http-lua libnginx-mod-http-ndk

CMD ["nginx", "-g", "daemon off;"]

Run as follows

docker run --rm -v `pwd`/nginx.conf:/etc/nginx/nginx.conf:ro -p 80:80 custom-nginx