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.
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
/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 https://github.com/golang/go/issues/36641
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 https://golang.org/doc/install/source#bootstrapFromBinaryRelease
## Compile Go from source https://golang.org/doc/install/source # install toolchain sudo apt update sudo apt install git golang -y # clone source cd ~ git clone https://go.googlesource.com/go 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
Step 2: Compile Ethereum with our toolchain
# install more toolchains sudo apt install git build-essential -y cd ~ git clone https://github.com/ethereum/go-ethereum.git 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) build/bin/geth
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 http://dweb.link/ipfs/QmWgJ68JocF15aBnsup6tcLnD6DbsMiXMjn4CsufmFuyLA -O geth