Background: I previously talked about my excitement for RISC-V, with one of my goals to see if I can get a decentralised web stack running on top of it. In my my first experiment I was able to get IPFS running on RISC-V.

Today: I was able to get Ethereum running on RISC-V, after finding upstreamed fixes that are not yet in the latest releases of Golang.
I have submitted a GitHub issue to track the progress of RISC-V support in go-ethereum.

Ethereum running on RISC-V

Checking Geth codebase for incompatibilities

First was to try compiling the Geth source with the latest version of Go 1.15.8. But I ran into an issue with cgo.

/usr/bin/ld: $WORK/b009/_x008.o: in function `x_cgo_thread_start':
/usr/lib/go-1.15/src/runtime/cgo/gcc_util.c:21: undefined reference to `_cgo_sys_thread_start'
collect2: error: ld returned 1 exit status

Digging into the Epic to port Golang to RISC-V, there are references to cgo not working. Following the threads you eventually get to the issue & PR that is tracking and resolving the cgo issues

The PR to fix this has been approved and merged, and is being upstreamed. But as of go 1.15.8 it has not yet been included. Which means for the moment we’ll need to compile Go ourselves from source to get this working

Building with latest patches

Step 0: Prepare your RISC-V environment

This walk-through is assuming you are running on a RISC-V system, or have set up your system for cross compiling.

Easiest: RISC-V emulator docker image Use docker to load a pre-built image that has a running RISC-V QEMU guest.

Emulated environment with QEMU:
I have written a guide on creating your own emulated RISC-V environment with QEMU: Emulating RISC-V Debian

Advanced: Cross compiling for RISC-V:
If you are not running an emulated environment, and want to build geth on your current machine. You can cross compile and target RISC-V in order to test out the toolchain, you can view my previous post on Cross compiling Golang for RISC-V.
Once you have riscv64-linux-gnu-gcc and Go environment set up, the rest of this walk-through will work.
NOTE: If you are cross compiling, you will also need to install libc6, see the bottom of my cross compiling link above, and see the troubleshooting section at the end.

Step 1: Compile Go from source

First, compile Go from source to get the cgo fix. The easiest way did this is via bootstrapping toolchain from binary release

## Compile Go from source
# install toolchain
sudo apt update
sudo apt install git golang -y

# clone source
cd ~
git clone goroot
cd goroot
cd src

# compile golang
./make.bash  # MUCH faster
./all.bash  # run this instead if you want all of the validation tests to run

Pay attention to where it installs the commands. in this case they are in /root/goroot/bin, but will be different on your system.
Go compiled

Step 2: Compile Ethereum with our toolchain

# install more toolchains
sudo apt install git build-essential -y

cd ~
git clone
cd go-ethereum

## Build geth using our compiled version of golang, targeting RISC-V.
# Pay attention to where your go binary was placed in previous step.
# on my system the built version was placed in /root/goroot/bin/go
## `make geth ` does not work, we need to run ci.go to specify the architecture
/root/goroot/bin/go run build/ci.go install -arch=riscv64 ./cmd/geth

# run your built geth! (if you are on RISC-V)

Ethereum running on RISC-V

Just give me a pre-built binary

I have pinned a version of Geth I built for you to try ONLY if you want to see it quickly working on your RISC-V system.
DO NOT use it for anything serious, as you should trust a version of Geth compiled by a random person on the internet ;-)

  • Risc-V geth download
  • Easy download command: wget -O geth