Tag Archives: raspberrypi

Building Go 1.5 on the Raspberry Pi

This is a short post to describe my recommended method for building Go on the Raspberry Pi. This method has been tested on the Raspberry Pi 2 Model B (900Mhz, 1Gb ram) and the older Raspberry Pi 1 Model B+ (700Mhz, 512Mb ram).

This method will build Go 1.5 into you home directory, $HOME/go.

As always, please don’t set $GOROOT. You never need to set $GOROOT when building from source.

Step 1. Getting the bootstrap Go 1.4 compiler

Go 1.5 requires an existing Go 1.4 (or later) compiler to build Go 1.5. If you have built Go from source on your host machine you can generate this tarball directly, but to save time I’ve done it for you.

% cd $HOME
% curl http://dave.cheney.net/paste/go-linux-arm-bootstrap-c788a8e.tbz | tar xj

Step 2. Fetch the Go 1.5 source

Fetch the Go 1.5 source tarball and unpack it to $HOME/go

% cd $HOME
% curl https://storage.googleapis.com/golang/go1.5.src.tar.gz | tar xz

Step 3. Configure your environment and build

Go 1.5 builds cleanly on arm devices, this is verified by the build dashboard, however if you want to see ./all.bash pass on the Raspberry Pi, some additional configuration is recommended.

Lower the default stack size from 8mb to 1mb.

This is necessary because the runtime tests create many native operating system threads which at 8mb per thread can exhaust the 32bit user mode address space (especially if you are running a recent Raspbian kernel). See issue 11959 for the details.

% ulimit -s 1024     # set the thread stack limit to 1mb
% ulimit -s          # check that it worked
1024

Increase the scaling factor to avoid test timeouts.

The default scaling factor is good for powerful amd64 machines, but is too aggressive for small 32 bit machines. This is done with the GO_TEST_TIMEOUT_SCALE environment variable.

Step 4. Build

% cd $HOME/go/src
% env GO_TEST_TIMEOUT_SCALE=10 GOROOT_BOOTSTRAP=$HOME/go-linux-arm-bootstrap ./all.bash
# Building C bootstrap tool.
cmd/dist

# Building compilers and Go bootstrap tool for host, linux/arm.
lib9
libbio
liblink
...
##### ../test

##### API check
Go version is "go1.5", ignoring -next /home/pi/go/api/next.txt

ALL TESTS PASSED

---
Installed Go for linux/arm in /home/pi/go
Installed commands in /home/pi/go/bin

On the Raspberry Pi 2 Model B, this should take around an hour, for the older Raspberry Pi 1 Model B+, it takes more than five!

Alternatively, you can substitute ./make.bash above to skip running the tests, which constitutes more than half of the time — or you could cross compile your program from another computer.

As a final step you should add $HOME/go to your $PATH, and to save disk space you can remove $HOME/go-linux-arm-bootstrap.

Testing Go on the Raspberry Pi running FreeBSD

This afternoon Oleksandr Tymoshenko posted an update on the state of FreeBSD on ARMv6 devices. The takeaway for Raspberry Pi fans is things are working out nicely. A few days ago a usable image was published allowing me to do some serious testing of the Go freebsd/arm port.

So, what works? Pretty much everything

[root@raspberry-pi ~]# go run src/hello.go
Hello, 世界

For the moment cgo and hardware floating point is disabled. I disabled cgo support early in testing after some segfaults, but it shouldn’t be too hard to fix. The dist tool is currently failing to auto detect1 support for any floating point hardware.

[root@raspberry-pi ~]# go tool dist env
GOROOT="/root/go"
GOBIN="/root/go/bin"
GOARCH="arm"
GOOS="freebsd"
GOHOSTARCH="arm"
GOHOSTOS="freebsd"
GOTOOLDIR="/root/go/pkg/tool/freebsd_arm"
GOCHAR="5"
GOARM="5"

This could be because the auto detection is broken on freebsd/arm, but possibly this kernel image does not enable the floating point unit. I’ll update this post when I’ve done some more testing.

At the moment performance is not great, even by Pi standards. The SDCard runs in 1bit 25mhz mode, and I believe the caches are disabled or set to write though. The image has been stable for me, allowing me to compile Go, and various ports required by the build scripts.

[root@raspberry-pi ~/go/test/bench/go1]# go test -bench=.
testing: warning: no tests to run
PASS
BenchmarkBinaryTree17    1        166473841000 ns/op
BenchmarkFannkuch11      1        83260837000 ns/op
BenchmarkGobDecode       5         518688800 ns/op           1.48 MB/s
BenchmarkGobEncode      10         225905200 ns/op           3.40 MB/s
BenchmarkGzip            1        16926476000 ns/op          1.15 MB/s
BenchmarkGunzip          1        2849252000 ns/op           6.81 MB/s
BenchmarkJSONEncode      1        3149797000 ns/op           0.62 MB/s
BenchmarkJSONDecode      1        6253162000 ns/op           0.31 MB/s
BenchmarkMandelbrot200   1        20880387000 ns/op
BenchmarkParse          10         250097600 ns/op           0.23 MB/s
BenchmarkRevcomp         5         279384200 ns/op           9.10 MB/s
BenchmarkTemplate        1        7347360000 ns/op           0.26 MB/s
ok      _/root/go/test/bench/go1        380.408s

If you are interested in experimenting with FreeBSD on your Pi, or testing Go on freebsd/arm, please get in touch with me.

Update: As of 6th Jan, 2013, benchmarks and IO have improved.

BenchmarkGobDecode             5         482796600 ns/op           1.59 MB/s
BenchmarkGobEncode            10         226637900 ns/op           3.39 MB/s
BenchmarkGzip          1        15986424000 ns/op          1.21 MB/s
BenchmarkGunzip        1        2553481000 ns/op           7.60 MB/s
BenchmarkJSONEncode            1        2967743000 ns/op           0.65 MB/s
BenchmarkJSONDecode            1        6014558000 ns/op           0.32 MB/s
BenchmarkMandelbrot200         1        19312855000 ns/op
BenchmarkParse        10         238778300 ns/op           0.24 MB/s
BenchmarkRevcomp               5         307852000 ns/op           8.26 MB/s
BenchmarkTemplate              1        6767514000 ns/op           0.29 MB/s

1. Did you know that Go automatically detects the floating point capabilities of the machine it is built on ?

Installing Go on the Raspberry Pi

Introduction

The Raspberry Pi has captured the imagination of hackers and makers alike. While it certainly wasn’t the first ARM development board on the market, its bargin basement price tag and the charitable philosophy of its inventors has sparked a huge interest in this little ARM system. What could be more appropriate for a new generation of programmers than a modern, safe and efficient programming language for their projects, Google Go.

This post describes the steps for installing Google Go from source on the Raspberry Pi. At the time of this post, trunk contains many improvements for ARM processors, including full support for cgo, which are not available in Go 1.0.x. It is expected that these enhancements will be available when Go 1.1 ships next year. If you are reading this post in September 2013, then it’s likely you will want to use the version of Go shipping with your operating system distribution rather than these instructions.

Update May, 2013 If you want to save yourself some time, precompiled binary releases of Go 1.1 for linux/arm are available. Please see the Unofficial ARM tarballs link at the top of the page.

Setting up your Pi

Before you compile Go on your Pi you should follow these steps to ensure a successful compilation. Briefly summarised, they are:

  1. Install Raspbian
  2. Configure your memory split
  3. Add some swap

Install Raspbian

The downloads page on the Raspberry Pi website contains links to SD card images for various Linux distributions. This tutorial recommends the Raspbian wheezy flavour of Debian. Follow the instructions for creating an SD card image and continue to the next step once you have ssh’d into your Raspbian installation.

Configure your memory split

The Pi comes with 256mb of memory which is shared between the video subsystem and the main processor. Compiling and linking Go programs can consume over 100mb of ram so it is recommended that the memory split be adjusted in favor of the main processor, at least while working with Go code. The Raspbian distribution makes this very easy with the raspi-config utility

% sudo raspi-config


Then reboot your system

% sudo shutdown -r now

Add some swap

To run the full test suite you will need some swap. This can be accomplished a variety of ways, using an external USB hard drive, or swapping over NFS. I’ll describe how to setup a NFS swap partition as this is the configuration I am using to generate this tutorial.

% sudo dd if=/dev/zero of=/import/nas/swap bs=1024 count=1048576 1048576+0 records in
1048576+0 records out
1073741824 bytes (1.1 GB) copied, 136.045 s, 7.9 MB/s
% sudo losetup /dev/loop0 /import/nas/swap
% sudo mkswap /dev/loop0
Setting up swapspace version 1, size = 1048572 KiB no label, UUID=7ba9443d-c64c-416f-9931-39e3e2decf0f
% sudo swapon /dev/loop0
% free -m
total used free shared buffers cached
Mem: 232 78 153 0 0 24
-/+ buffers/cache: 52 179
Swap: 1123 15 1108

Installing the prerequisites

Raspbian comes with almost all the tools you need to compile Go already installed, but to be sure you should install the following packages, described on the golang.org website.

% sudo apt-get install -y mercurial gcc libc6-dev

Cloning the source

% hg clone -u default https://code.google.com/p/go $HOME/go warning: code.google.com certificate with fingerprint 9f:af:b9:ce:b5:10:97:c0:5d:16:90:11:63:78:fa:2f:37:f4:96:79 not verified (check hostfingerprints or web.cacerts config setting)
destination directory: go
requesting all changes
adding changesets
adding manifests
adding file changes
added 14430 changesets with 52478 changes to 7406 files (+5 heads) updating to branch default
3520 files updated, 0 files merged, 0 files removed, 0 files unresolved

Building Go

% cd $HOME/go/src % ./all.bash

If all goes well, after about 90 minutes you should see

ALL TESTS PASSED

---
Installed Go for linux/arm in /home/dfc/go
Installed commands in /home/dfc/go/bin

If there was an error relating to out of memory, or you couldn’t configure an appropriate swap device, you can skip the test suite by executing

% cd $HOME/go % ./make.bash

as an alternative to ./all.bash.

Adding the go command to your path

The go command should be added to your $PATH

% export PATH=$PATH:$HOME/go/bin
% go version
go version devel +cfbcf8176d26 Tue Sep 25 17:06:39 2012 +1000

Now, Go and make something awesome.

Additional resources