K2 is an operating system for energy-efficient mobile System-on-chip. It is being developed by researchers at Rice University.

Prepare for build

Overview of source code

Set up the environment

Host machine

Install Ubuntu 12.04 LTS. 13.10 should be fine as well.

Cross-toolchain for kernels

Install Linaro GCC 4.6.3 (2012.02) arm-linux-gnueabi.

Speed up compilation

We use ccache and distcc.

(host)$ sudo apt-get install ccache distcc

We also find the tips from Hugh Blemings very informative.


Start from installing Linaro developer image 12.10 on Panda, and install necessary packages including SSH and NFS.

Unzip and copy a bunch of programs and scripts to the Panda under /root/.

Panda PXE boot (optional) for serious hacking

In developing K2, we need to reboot Panda very often. To avoid repeatedly plugging/unplugging the SD card, we have been loading the OS image from a TFTP server.

Basic instructions on setting up TFTP server for Panda can be found on Linaro and this blog.

Populate the TFTP root

Our TFTP server root can be found here (open in a new tab), which can be used as a boilerplate.

Prepare Panda for PXE boot

We need to generate the right boot.scr for Panda u-boot from a boot.txt. Take a look at our boot.txt, and replace the IP address with that of your TFTP server. Generate boot.scr, and copy it to the SD card boot partition. For example:

mkimage -A arm -T script -C none -n "My Boot.scr" \
-d ./boot.txt \
cp boot.scr /media/boot/


The K2 source comes with a handy set of shell functions to simply the build procedure. To load them, do:

# enter the directory of kage-env.sh
source kage-env.sh

Build the custom assembler

Get the modified assembler that adds -mreplace-blx option (tarball). It is based on GNU binutils 2.22.

Build it following the standard procedure:

make binutils
make cross-binutils

Replace arm-linxu-gnuieabi-as installed above with a symlink to build/binutils/gas/as-new.

Build the toolchain for Cortex-M3 user space

User code running on Cortex-M3 cannot use the stock glibc. In particular, the user code needs to use the M3 version of kernel helpers.

The source of modified arm-none-linuxgnueabi toolchain can be found here. tarball See Makefile in the root directory for building instructions.

Build the Cortex-M3 user space

Use the toolchain generated from the step above to compile M3 user code located under ${KROOT}/kernel/init.

Change the paths in ${KROOT}/kernel/init/Makefile to point to your toolchain. Then choose one of the available user programs under ${KROOT}/kernel/init/ to be built as init, which will be firstly executed by the M3 kernel. For instance, if want to do that for syscall:

cd ${KROOT}/kernel/usr/init
mv -f init /tmp/ && ln -s syscall/init
cd ${KROOT}/kernel/init/syscall
make clean

Build kernels

(host)$ kage-build-a9
(host)$ kage-build-m3

Install kernels

  • If Panda is NOT networked, manually copy the kernel to the boot partition of Panda SD card, for example:

(host)$ cp ${KROOT}/../out/a9/arch/arm/boot/uImage /media/boot
  • If PXE boot is up, to upload the A9 kernel to the TFTP server:

(host)$ kage-install-a9
  • If Panda is NOT networked, manually copy kernels to the Panda SD card /root/. For instance,

(host)$ cp ${KROOT}/../out/m3/vmlinux /media/rootfs/root/
  • If Panda is networked with SSH server running, to copy the M3 kernel over SSH:

(host)$ kage-install-m3

Run kernels


Just power cycle the Panda.


Must load it from a running A9 user space. In a Panda terminal, do

(panda)$ cd /root/ && ./load