Working with the source

You may want to first try to build K2 from source. Note that all the instructions here assume that you have loaded K2 scripts with source right from its own directory.

Alternative OS configurations

There are multiple kernel configuration files under ${KROOT} named as kage-{a9|m3}-XXXX. For instance, to build the M3 kernel for testing the shared DMA driver, do

(host)$ cd ${KROOT}/../out/m3/
# save the current config
(host)$ DATE=$(date +"%Y%m%d%H%M")
(host)$ mv .config /tmp/m3-config-$DATE.config
(host)$ cp ../../kernel/kage-m3-dmatest .config
(host)$ kage-build-m3

User programs

User program is bundled with the M3 kernel image with Linux’s ramdisk facility.

Sources: Multiple of them are located under user/init/. They exercise different parts of the OS.

The step of building the M3 user space above actually reads ${KROOT}/initramfs-list-min and produces a ramdisk image ${KROOT}/usr/initramfs_kage.cpio, which will be embedded into the final M3 kernel.

Regression Test

Clean all
kage-clean-a9; kage-clean-m3
the A9 kernel
User program on the M3 kernel
## check out some commit. eg git co 2c8e2ab

## use the right config ...
cd ${KROOT}/../out/m3
# save the current config
DATE=$(date +"%Y%m%d%H%M")
mv .config /tmp/m3-config-$DATE.config

# copy over the config
cp ../../kernel/kage-m3-min_defconfig .config
# minimum dbg info, only available in recent commits.
../../kernel/scripts/config --set-val KAGE_GLOBAL_DEBUG_LEVEL 50

### 1st pass

### user space
cd /home/xzl/Kage/kernel/tilt/kernel/usr/init
rm -f init
ln -s syscall/init

cd /home/xzl/Kage/kernel/tilt/kernel/usr/init/syscall
make clean

## make sure see "[OK]. now go ahead to build the kernel"
## then go head to the 2nd pass.

### 2nd pass
kage-build-m3 && kage-install-m3

If all goes well, do

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



The tracebuffer is a non-cached memory region shared among processors. See hw_headers.c for more information about the memory layout.

Output to UART

The output of k2_print() can be directed to the tracebuffer or UART3 — the only UART that has a physical connector on Pandaboard. If doing so, kernel messages from both Cortex-A9 and -M3 will be interleaved on that UART. See kage_enable_uart() for more.

Build kernel with a specific debugging level
(host)$ cd ${KROOT}/../out/m3/
# save the current config
(host)$ DATE=$(date +"%Y%m%d%H%M")
(host)$ mv .config /tmp/m3-config-$DATE.config
(host)$ cp ../../kernel/kage-m3-dmatest .config
(host)$ ../../kernel/scripts/config --set-val KAGE_GLOBAL_DEBUG_LEVEL 50
JTAG debugger

A handful of debuggers support Pandaboard, e.g., Spectrum Digital’s XDS560V2. Combining with TI’s CCS IDE, you should be able to debug the CPU/GPU/DSP of OMAP4. They would be useful in the bringing up procedure.

Notes on Internals

Limited by our time, these notes are never exhaustive. They’d better be used as references to our source code, where comments have provided more details.


K2 boots in two stages, one for each kernel. The A9 kernel boots just like usual Linux and reserves contiguous memory for the M3 kernel’s private region.

The two kernels of K2 bootstrap in different ways. The one for A9 boots as normal Linux kernel (from u-boot). After the userspace is up, the A9 kernel loads the M3 kernel (vmlinux in elf) with Linux rproc framework, and hot-plugs the latter onto itself.

Noteable sources


The header data structure of the M3 kernel that is understood by the A9 rproc kernel loader.


The M3 kernel startup code and debugging support.


Debugging message API.


Software cache coherence.


The procfs interface to inspect/debug the Cortex-A9 kernel.


The fault handling code for the Cortex-M3 kernel.


The software TLB entries for the Cortex-M3 L1 MMU.


Basic functions for maintaining the Cortex-M3 L1 MMU.


The software performance counters for K2 events.


The shared DMA driver.

Physical memory layout

The OMAP4 has 1GB physical memory, starting from the physical address 0x8000:0000.

0x8000:0000 — 0x8600:0000 (96M)

The M3 kernel area. The identical virtual address range maps to it.

0x8600:0000 — 0x8640:0000 (4M)

The K2 boot loader area (aka Kage section in the source code). The last 512KB of this area (0x8638:0000 — 0x8640:0000) is the debugging tracebuffer. Virtul address range is 0x7fc0:0000 — 0x8000:0000.

0x8800:0000 — 0xc000:0000

The A9 kernel area.

For more information, see

  • arch/arm/mach-omap-m3/include/mach/memory.h

  • arch/arm/kernel-m3/fw_headers.c