Building the Android kernel

Posted: August 18, 2011 in Android, Embedded System, Linux

Building the Android kernel

Velibor Cakarevic

Downloading Android kernel code

If you download Android 2.1 platform you will not get the source code of the kernel. This is due to that there is quite a huge amount of code needed to be downloaded, it takes time to build the kernel and not many application developers are interested in the kernel code. Below is a description of how to download the Android source code and compile it for ARM, using Linux as your OS. Note that porting to hardware is not in the scope of this description.

First go to your home directory and create a directory where you wish to work in, e.g. myAndroid and step into that directory. Note that ‘$’ is not part of a command but illustrates in this document the commands.
$ cd ~
$ mkdir myAndroid
$ cd myAndroid

To clone the common Android kernel and get the kernel code use the command:

$ git clone git:// android-kernel

The command creates a new folder called ‘android-kernel’ (you can choose another name if you wish) in your ‘myAndroid’ folder and downloads the kernel code.

Go to that folder:

$ cd android-kernel

Building the Android kernel code

Android relies on Linux version 2.6. When building the kernel you will do these commands:
$ make menuconfig
$ make

The command ‘make menuconfig’ configures the kernel. This process involves specifying what functionality to put into the kernel. Additionally, decisions have to be made (when possible) whether kernel code should be statically or dynamically linked. Statically linking means that all modules are built and linked into the kernel. Optimized static kernels execute much faster, since there are no shared object lookups and their binary size is smaller.

With dynamic loading you can choose to manually load the modulus to the kernel by using insmod or modprobe tool/command. Loadable kernel modules allow changing code during runtime. Loadable modules are pieces of kernel code which are not linked (included) directly in the kernel. One compiles them separately, and can insert and remove them into the running kernel at almost any time. If you want a module to be dynamically loaded give it the option <M> during ‘make config’ procedure.

If you want to make an own module you should enable the module support after doing ‘make menuconfig’

Loadable module support —> [*] Enable loadable module support

When building for another processor architecture than the one that your host processor uses you must use a crosscompiler and set the architecture parameter. This will show you how to compile the code for an ARM processor architecture. Before doing ‘make menuconfig’ set the architecture parameter:

$ export ARCH=arm

Now start the configuration of the kernel:

$ make menuconfig

Picture 1 shows the menu when configuring the kernel.

After having modified the configuration you will at the exit be prompted by a question, whether you wish to save the changes. Choose Yes if you want to do so. You can check the generated .config file by:

$ nano .config

To set the crosscompiler use do the command:

$ export CROSS_COMPILE=arm-unknown-linux-gnueabi-

Note! I am using a compiler that you may not have. If you have downloaded the whole Android 2.1 platform (perhaps you have it in another folder) you could use

In that case the command to set the cross-compiler as the one delivered and precompiled in the Android platform is:

$ export CROSS_COMPILE=~/your_android_platform_folder/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-

Make starts the build process and builds the kernel according to the configuration file. To start the build process do:

$ make

The image is generated in the folder: arch/arm/boot/zImage

If you wish to search for the zImage use the find command:
$ find -name ‘zImage’

Some tips

When configuring the kernel in the menu (see figure 1) there may be some flags that you cannot remove. However you can still modify the ‘.config’-file directly if you wish to. You should on the other hand be sure of what you are doing. When building again, i.e. make you will be prompted by a question if you wish to keep that flag. Press ‘n‘ to exclude the module. If this question does not appear it is most likely that the module has not been removed.

When working with building of the kernel, the best approach is to remove modules that are not necessary in your kernel, and when adding new modules add them step by step. This will give you a fair chance to fix errors such as build failures, but also track down crashes when running on target.

When you have build errors and keep removing flags (i.e. modules) it is good to remove the object files and make a new build. Removing the objectfiles and rebuilding the kernel is done accordingly:
$ make clean
$ make

Edited 5 times. Last edit by KennyLeopold Amanda on Apr 22, 2011 at 8:46:27 PM (about 15 weeks ago).
March 15, 2011 3:35:08 PM PDT (22 weeks ago)
PhotoJayson Burak

BAE Systems
Member since Mar 15, 2011
Posts: 1
Hi there,

I apologize for asking a stupid question, but I’m curious as to what the next steps are from here, once the new zImage has been created…or in other words, how do I get the zImage loaded on the device? I have found a few different options, but none of them seem to work for me. What I mean by that is that whenever I try to flash new kernel or new boot image (kernel + ramdisk) to my device, it does not load. I don’t get any errors during the build or make process. So, I am either flashing the device wrong or something else that I have no knowledge of. Any help would be appreciated. Thanks.

~ Jay

March 16, 2011 1:25:26 AM PDT (22 weeks ago)
PhotoVelibor Cakarevic

Member since Apr 22, 2010
Location: Malmo
Posts: 2
Hello Jayson,

It is hard to tell what might be causing the device not to display the home screen. If you flash procedure would fail then you should get an error message during that procedure.

The zImage is an compressed code that is unzipped at the boot procedure. You can see the procedure in the command prompt when the device boots up (some boot-loaders print a dotted line to animate the procedure). If it is uncompressed then that should be a good sign, that you have flashed it ‘corrrectly’ (but I am comparing to my own projects). You tell the bootloader (set the environment variables) which memory address the image is stored at. I do not know which bootloader you are using but Uboot is the one I have been using [1].

Further you might not have the correct driver code for the display. Such driver code (Linux driver code) should be delivered to you by the vendor. You could ask them about this issue as well.

Have you enabled/added the display driver module (in the “make menuconfig”)? If it is statically linked (‘*’) it is built in the kernel. If it is dynamically linked (‘M’) then the kernel will load/insert the module in the runtime. You can also insert the modules manually by the ‘insmod’ [2] or ‘modprobe’ [3] command.

One tip is to mount the device’s filesystem on to a laptop (done in the bootloader by setting parameters) i.e. you boot up the device but the device gets the filesystem from a folder on your laptop. From there you can insert modules. This approach (mounting the filesystem) makes is ‘easier’ to work since you (most probably) have more space on your laptop then on your device and do not have to flash the filesystem on your device (saves you time).

Further if you are using Beagleboard, then there are ported versions of Android for their device.[4]

Google has also added some information since I posted this article. Please have a look at the “Android Platform Developer´s Guide” [5]

In order to help you I would have to be sitting next to you.




Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s