Posted on March 8, 2019
Running Go on VIA ARM devices
Go is a modern and quite popular systems programming language developed at Google. I’ve recently came across a wiki page describing its ARM support, I thought it would be interesting to check how VIA devices can make use of Go. I’ve checked out the VAB-820, VAB-600, and the APC 8750 boards, all a bit different from each other.
VAB-820 with a Gopher
I found that the general documentation does not cover all the things that can (and generally do) go wrong, though a few online searches usually pointed me in the right direction. Installing Go needs two separate steps: bootstrapping first, then compiling from source.
Bootstrap is needed because Go’s now written in Go, so you need to already have Go to get Go. That makes sense, right? There are two ways go about this (pun intended). Either use another system (e.g. an x86 computer) that can create a bootstrap package for ARM, or use the Go package from the ARM board’s distro. My VIA boards are running Debian, and there the available Go version is pretty old. So instead I opted to an x86 bootstrap. These next steps are based on information at the Install Go from Source page.
First downloaded Go 1.4 from their binary distribution page, and put it into the ~/go1.4/ directory as that’s where Go looks for the binaries by default.
Next cloned the latest Go source from Github, and used it to create a bootstrap package
$ git clone https://github.com/golang/go.git
$ cd go/src/
$ GOOS=linux GOARCH=arm GOARM=7 ./bootstrap.bash
[lots of stuff]
Bootstrap toolchain for linux/arm installed in /home/user/go-linux-arm-bootstrap.
-rw-r–r– 1 user user 48983241 Nov 18 16:55 /home/user/go-linux-arm-bootstrap.tbz
In the settings above the GOOS environmental variable selects Linux, GOARCH selects ARM support in general, and GOARM selects ARMv7 support. Working with these settings, since both VAB-820 and VAB-600 are ARMv7 devices, Other values are listed in the installation guide.
To make it easy, I’ve made our current precompiled bootstrap files available for download for ARMv7, ARMv6, and ARMv5.
The rest of the steps take place on the board itself. Boot up, and set up networking. Copy the “go-linux-arm-bootstrap-X.tgz onto the board and extract it, for example into the user directory. Clone the Go source as well, and then things are almost ready.
Almost, because ARM devices are generally underpowered compared to x86, or at least their CPU/memory/stack balance is very different than an x86 machine. Because of this, some of the settings need to be modified to successfully build Go. Based on a blogpost, the stack size needs to be reduced (e.g. from 8MB to 1MB) with “ulimit -s 1024”, and the Go tests scaling factors need to be modified through an environmental variable.
And one more trick before starting: the compilation makes heavy use of “/tmp” and it is better to make sure it’s in the memory, not trashing the SD Card or eMMC storage. The wiki recommends these settings in “/etc/fstrab”
tmpfs /tmp tmpfs nodev,nosuid,mode=1777 0 0
The final process is something like this:
$ tar xjvf go-linux-arm-bootstrap-armv7-.tbz
$ git clone https://github.com/golang/go.git
$ cd go/src
$ ulimit -s 1024
$ GO_TEST_TIMEOUT_SCALE=10 GOOS=linux GOARCH=arm GOARM=7 GOROOT_BOOTSTRAP=~/go-linux-arm-bootstrap ./all.bash
[now wait for a long time]
ALL TESTS PASSED
Installed Go for linux/arm in /home/user/go
Installed commands in /home/user/go/bin
*** You need to add /home/user/go/bin to your PATH.
In the process first Go is compiled, then all the tests are run that are included in the source repository. That’s the part that takes the longest time. If all the tests passed, then the new go binary will be installed in the “bin” directory of the git repository – and now ready to use!
On VAB-820 I’ve managed to successfully install Go through these steps, and using the ARMv7 bootstrap kit. Its quad core performance is pretty good, and can’t wait to try it for some practical projects! (Might need to permanently set the stack size to 1MB like above.)
There’s also a simpler way to possibly get to use Go: turns out that Resin.io, which has (alpha) support for VAB-820, has some Go base Docker images, so deploying an application onto the board can be as easy as a “git push”. This is still very experimental at the moment, so things will likely to change.
The process is quite similar on VAB-600 as well, though it takes longer time, because it’s a single core ARMv7 device. Nevertheless it works, and provides some interesting options for projects! (Might need to permanently set the stack size to 1MB like above.)
The APC 8750 is an ARMv6 device, and should be okay to bootstrap with a ARMv6 kit, but it turns out that it also depends on the OS version run. The board I had at hand was running soft-float Raspbian, and there the compilation failed with some floating point errors. Looks like that in this case, using a ARMv5 (“GOARM=5”) bootstrap kit might do the trick. The compilation takes quite a long time, though, naturally.
As the next step, you can look around at the tutorial section, and at Awesome Go for great project examples and recommended libraries.
Have you tried Go with any VIA boards, or any other ARM devices? Have any interesting Go project that you want to show off? Would love to hear your experience in the comments!