Skip to content
Preetam D'Souza edited this page May 13, 2018 · 8 revisions

The kernel is the lowest-level software service running on a standard computing system. Amongst it's many roles, it facilitates a consistent and safe environment for userspace programs (everything above the kernel, i.e. all the software a typical user interacts with) to run.

Maru's kernel is almost the same as a stock device kernel. The difference is in the kernel configuration file.

Kernel Building

Let's take the Nexus 5 (hammerhead) as an illuminating example of how to build a kernel for Maru.

Get the source

In general, the kernel sources for Nexus devices can be found in the AOSP's table of kernel sources.

hammerhead runs on a Qualcomm Snapdragon 800 (MSM8974 part number), so we need to grab the "msm" kernel.

Instead of grabbing the stock repository though, we will use Maru's own repository, which is identical with the exception of containing Maru's kernel configuration and some general tidying up of unused branches.

$ git clone https://github.com/maruos/android_kernel_msm.git

To build a kernel for Maru v0.3, which is based on Android 6.0.1, we will checkout the hammerhead-3.4-marshmallow-mr3 branch.

Tip: These branches are based on upstream AOSP branches and have the same naming scheme. You can easily find the appropriate branch name for a device by appending the codename, kernel version, and translated Android version. "hammerhead" is the codename, "3.4" is the kernel version, and "marshmallow-mr3" refers to Android 6.x.y ("marshmallow")

$ git checkout hammerhead-3.4-marshmallow-mr3

If you are building for master, use the kernel repository's default branch.

Get the right toolchain

Before you can build anything, you need to have access to the right toolchain for compiling the kernel.

A fail-safe rule is to use the latest Android-recommended prebuilt toolchain for your hardware. That's arm-eabi-4.8 for hammerhead.

Tip: You can find the prebuilt toolchain in your AOSP work directory after you've done a standard repo sync.

Include the prebuilt toolchain in your path:

$ export PATH=/path/to/aosp/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin:$PATH

And let the kernel make system know you want to use that specific toolchain:

$ export CROSS_COMPILE=arm-eabi-

Select your hardware architecture

Next, let the kernel know which architecture you plan to build. This is "arm" for hammerhead (and most other mobile devices):

$ export ARCH=arm

Define your kernel config

Ok, here is where things get different from the standard AOSP kernel build.

Maru relies on the Linux kernel's cgroup and namespace support for providing clean isolation via containers. You need to enable the following minimum options in your device's defconfig, in addition to the standard AOSP ones, to get Maru to fully work:

CONFIG_CGROUP_DEVICE=y
CONFIG_CPUSETS=y
CONFIG_DEVTMPFS=y
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
CONFIG_NAMESPACES=y
CONFIG_SYSVIPC=y

One important note on CONFIG_NAMESPACES: If you set CONFIG_NAMESPACES=y in your defconfig, it usually selects all the necessary namespace options (CONFIG_PID_NS, CONFIG_UTS_NS, etc.) unless there is a line in your defconfig like # CONFIG_PID_NS is not set. If your stock defconfig includes these lines, make sure to delete them or those options will be disabled in your kernel even if you correctly have CONFIG_NAMESPACES=y!

Tip: Some device kernels fail to compile with CONFIG_USER_NS=y, which is selected by default by CONFIG_NAMESPACES=y. This is optional for Maru OS, so you can disable it (add a line # CONFIG_USER_NS is not set in your defconfig) if it's causing build errors.

Since Maru has already been ported to hammerhead, this config has already been created for you. Just tell the kernel's make system to use maru-hammerhead_defconfig:

$ make maru-hammerhead_defconfig

This will use the selected defconfig as a base config and fill out all the default options for you, placing the final kernel config in .config in the top-level folder of your kernel sources.

Build it!

$ make -jX

...where X is the number of CPU cores on your dev machine.

The final kernel binary (for arm anyways) can be found at arch/arm/boot/zImage-dtb.

References