Last Man On Earth : Github Thoughts
This a simple tutorial to describe step-by-step how to create an environment to cross compile Go applications to run on a BeagleBone Black using Buildroot toolchain.
root
.Install essential things first
apt-get update
apt-get install -y build-essential libncurses5-dev \
bzr cvs git mercurial rsync subversion \
libc6 libstdc++6 libncurses5 zlib1g lzop u-boot-tools \
tftpd-hpa nfs-kernel-server sqlite3 picocom
Download and extract the Buildroot release (e.g: 2015.02) on /opt/toolchain/
directory:
mkdir -p /opt/toolchain
cd /opt/toolchain
wget http://buildroot.uclibc.org/downloads/buildroot-2015.02.tar.gz
tar -xzvf buildroot-2015.02.tar.gz
cd buildroot-2015.02
It's already have a previous configuration to BeagleBone Black describe in
configs/beaglebone_defconfig
, so, it's a nice way to follow.
Invoke those commands bellow to generate a Makefile
and configure the system:
make beaglebone_defconfig
make menuconfig
Here are some settings you should change on buildroot config (yeah!...I'll use sqlite...)
Target Options --->
ARM instruction set (Thumb2)
Toolchain --->
Toolchain type (Buildroot toolchain) --->
Kernel Headers (Linux 3.12x kernel headers) --->
C library (eglibc) --->
[*] Enable C++ support
[*] Build cross gdb for the host
[*] Purge unwanted locales
(C en_US de fr pt_br) Locales to keep
(en_US) Generate locale data
[*] Enable MMU support
[*] Register toolchain within Eclipse Buildroot plug-in
System configuration --->
[*] Install timezone info
(default) timezone list
(America/Sao_Paulo) default local time
Kernel --->
[] Linux Kernel
Target packages --->
Libraries --->
Database --->
[*] sqlite
[*] Command-line editing
[*] Additional query optmizations (stat3)
[*] Enable version 3 of the full-text search engine
Network applications --->
[*] dhcpd
[*] iptables
[*] iputils
[*] openssh
Filesystem images --->
[*]tar the root filesystem
Compression method (no compression)
Save, exit and initiate a full system build (This will take a while...):
make all
OK, get the u-boot
files and move them to a more visible directory (e.g.:/opt/toolchain/output/
):
mkdir -p /opt/toolchain/output
cp -a /opt/toolchain/buildroot-2015.02/output/images/MLO /opt/toolchain/output/
cp -a /opt/toolchain/buildroot-2015.02/output/images/u-boot.img /opt/toolchain/output/
cp -a /opt/toolchain/buildroot-2015.02/output/images/Env.txt /opt/toolchain/output/
Now, run to the hills...
Download the Linux kernel 3.12 directly from BeagleBone Github repository:
mkdir -p /opt/toolchain/linux
git clone -b 3.12 git://github.com/beagleboard/kernel.git /opt/toolchain/linux
cd /opt/toolchain/linux
bash ./patch.sh
cp configs/beaglebone kernel/arch/arm/configs/beaglebone_defconfig
wget http://arago-project.org/git/projects/?p=am33x-cm3.git\;a=blob_plain\;f=bin/am335x-pm-firmware.bin\;hb=HEAD -O kernel/firmware/am335x-pm-firmware.bin
Setting the arm-linux-gcc
to your $PATH
:
export PATH=$PATH:/opt/toolchain/buildroot-2015.02/output/host/usr/bin/
Compile and generate an uImage file with a DTB blob, and kernel modules (This will take a while,again...)
cd /opt/toolchain/linux/kernel
make ARCH=arm CROSS_COMPILE=arm-linux- beaglebone_defconfig -j2
make ARCH=arm CROSS_COMPILE=arm-linux- uImage dtbs LOADADDR=0x80008000 -j2
make ARCH=arm CROSS_COMPILE=arm-linux- modules -j2
Copy uImage and DTB file to /opt/toolchain/output
directory:
cp -a /opt/toolchain/linux/kernel/arch/arm/boot/uImage /opt/toolchain/output
cp -a /opt/toolchain/linux/kernel/arch/arm/boot/dts/am335x-boneblack.dtb /opt/toolchain/output/
Untar rootfs generated by buildroot to install kernel modules:
mkdir -p /opt/toolchain/rootfs
tar -xvf /opt/toolchain/buildroot-2015.02/output/images/rootfs.tar -C /opt/toolchain/rootfs
make ARCH=arm CROSS_COMPILE=arm-linux- INSTALL_MOD_PATH=/opt/toolchain/rootfs modules_install
make ARCH=arm CROSS_COMPILE=arm-linux- INSTALL_MOD_PATH=/opt/toolchain/rootfs firmware_install
The great advantage of using NFS is that you compile binaries on your development environment, install binaries and export them, have instant response on your target system.
Edit /etc/exports
file, including the following line:
/opt/toolchain/rootfs *(rw,sync,fsid=0,no_root_squash,crossmnt,no_subtree_check,no_acl)
So, restart the NFS service: /etc/init.d/nfs-kernel-server restart
.
Copy uboot files and kernel uImage to tftpboot
directory:
mkdir -p /var/lib/tftpboot/boot/
cp -a /opt/toolchain/output/uImage /var/lib/tftpboot/boot/
cp -a /opt/toolchain/output/MLO /var/lib/tftpboot/boot/
cp -a /opt/toolchain/output/u-boot.img /var/lib/tftpboot/boot/
cp -a /opt/toolchain/output/am335x-boneblack.dtb /var/lib/tftpboot/boot/
Connect the BeagleBone to your serial port via uart1 (Debug Serial Header), and set commands in u-boot, to load your linux kernel from tftp and rootfs over NFS:
set ipaddr 192.168.0.15
set serverip 192.168.0.50
set gateway_ip 192.168.0.1
set rootpath '/opt/toolchain/rootfs/production'
set loadtftp 'tftpboot 0x80200000 /boot/uImage; tftpboot 0x815f0000 /boot/am335x-boneblack.dtb'
set netargs 'setenv bootargs console=${console} ${optargs} root=/dev/nfs nfsroot=${serverip}:${rootpath},${nfsopts} rw ip=dhcp'
set uenvcmd 'setenv autoload no;run loadtftp; run netargs; bootm 0x80200000 - 0x815f0000'
run uenvcmd
1.4.2 it's a good start, I'll check go 1.5 later.
wget https://storage.googleapis.com/golang/go1.4.2.linux-amd64.tar.gz
tar -xzvf go1.4.2.linux-amd64.tar.gz -C /opt/
cd /opt/go/src
GOOS=linux GOARCH=arm ./make.bash --no-clean
rm go1.4.2.linux-amd64.tar.gz
Feel more confortable using a local GOPATH like:
cd $HOME
mkdir -p go
Set my $USER
profile (.bashrc
):
export GOROOT="/opt/go"
export GOPATH="$HOME/go"
export PATH=$PATH:/opt/go/bin
Create a simple go app:
package main.go
import "fmt"
func main() {
fmt.Printf("Hello BeagleBone Black\n")
}
Using Makefile
to the dirty job:
TARGET := hello
all:
go build -o $(TARGET) $^
beagle:
CC=arm-linux-gcc CGO_ENABLED="1" GOARM=7 GOARCH=arm GOOS=linux go build -o $(TARGET) $^
clean:
go clean
install:
cp -a $(TARGET) /opt/toolchain/rootfs/root/
Compile and install (copy TARGET to rootfs directory):
make beagle ; make install
VoilĂ , we have a cross-compiled go binary ready to running on a BeagleBone Black.