Building the Android Kernel

Posted on May 5, 2010 (4 years ago). Seen 62,076 times. 12 comments. Permalink Feed
Member since Apr 22, 2010
Location: Munich
Stream Posts: 0
Tagged as: Android Tutorial

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


Posted on Mar 15, 2011
Photo Jayson Burak
BAE Systems
Member since Mar 15, 2011
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
Posted on Mar 16, 2011
Photo Velibor Cakarevic
Member since Apr 22, 2010
Location: Munich
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.

Posted on Mar 23, 2011
Photo Preetam Bhosle
Member since Mar 23, 2011
I have successfully compiled Linux kernel for android:

root@ubuntu:~/common# ARCH=arm CROSS_COMPILE=~/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- make
CHK include/linux/version.h
make[1]: `include/asm-arm/mach-types.h' is up to date.
CHK include/linux/utsrelease.h
SYMLINK include/asm -> include/asm-arm
CALL scripts/
<stdin>:1097:2: warning: #warning syscall fadvise64 not implemented
<stdin>:1265:2: warning: #warning syscall migrate_pages not implemented
<stdin>:1321:2: warning: #warning syscall pselect6 not implemented
<stdin>:1325:2: warning: #warning syscall ppoll not implemented
<stdin>:1365:2: warning: #warning syscall epoll_pwait not implemented
CHK include/linux/compile.h
Kernel: arch/arm/boot/Image is ready
Kernel: arch/arm/boot/zImage is ready
Building modules, stage 2.
MODPOST 157 modules

but i get the following error while loading this images in the emulator:

root@ubuntu:~/android-sdk-linux_x86/tools# ./emulator -avd avd1.5 -kernel ~/common/arch/arm/boot/zImage -show-kernel -verbose
emulator: found SDK root at /home/preetam/android-sdk-linux_x86
emulator: root virtual device file at /home/preetam/.android/avd/avd1.5.ini
yaffs_read_super: isCheckpointed 0
sh: can't access tty; job control turned off
# init: cannot find '/system/bin/playmp3', disabling 'bootsound'
init: cannot find '/system/bin/dbus-daemon', disabling 'dbus'
eth0: link up
init: untracked pid 578 exited
init: untracked pid 579 exited
warning: `rild' uses 32-bit capabilities (legacy support in use)
init: untracked pid 601 exited
init: untracked pid 592 exited
init: untracked pid 605 exited
init: untracked pid 602 exited
init: untracked pid 609 exited
init: untracked pid 606 exited
init: critical process 'servicemanager' exited 4 times in 4 minutes; rebooting into recovery mode
save exit: isCheckpointed 1
save exit: isCheckpointed 1
Restarting system with command 'recovery'.
Reboot failed -- System halted

and the emulator didn't start with the new kernel image(emulator didn't reboot). what is the problem here..?? and how can i replace my emulator's image with newly compiled Linux permanently??

please help. thank you!
Posted on Apr 22, 2011
Photo KennyLeopold Amanda
Member since Apr 22, 2011
This is very Nice post you mentioned here.
Posted on Aug 17, 2011
Photo Ruturaj Patil
engineering student
Member since Aug 17, 2011
Hello, Im a student from Pune University. I need to develop a loadable kernel module for android platform as my BE project. Can you please suggest tools and sites for understanding the methods to develop such module? Are LKMs available for download which can be edited?
Posted on Oct 5, 2011
Photo Shubham Patni
Member since Sep 12, 2011
hello , thanks for such a good post.
any one have idea how to enable GPIO functionality for kernel build.

I want to perform some event on press of any Hard Button (like : volume etc).

When I seen in default directory structure /dev/input/ it shows me event0,event1...,mic
but when i seen in adb shell /dev/input directory I got nothing.

I tried with Device Driver - > Input device support ..and again build uImage and use it.
but stl showing nothing in /dev/input directory.

Am I assuming something wrong, pls guide me.
Posted on Feb 14, 2012
Photo Vinayaka Hegde
Member since Feb 14, 2012
When I do make menuconfig I get the following error

"HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/lxdialog/checklist.o
HOSTCC scripts/kconfig/lxdialog/inputbox.o
HOSTCC scripts/kconfig/lxdialog/menubox.o
HOSTCC scripts/kconfig/lxdialog/textbox.o
scripts/kconfig/lxdialog/textbox.c: In function ‘print_line’:
scripts/kconfig/lxdialog/textbox.c:323:9: warning: variable ‘x’ set but not used [-Wunused-but-set-variable]
scripts/kconfig/lxdialog/textbox.c:323:6: warning: variable ‘y’ set but not used [-Wunused-but-set-variable]
HOSTCC scripts/kconfig/lxdialog/util.o
HOSTCC scripts/kconfig/lxdialog/yesno.o
HOSTCC scripts/kconfig/mconf.o
HOSTCC scripts/kconfig/
HOSTLD scripts/kconfig/mconf
scripts/kconfig/mconf.o: In function `main':
mconf.c:(.text.startup+0x66): undefined reference to `initscr'
scripts/kconfig/lxdialog/checklist.o: In function `print_arrows':
checklist.c:(.text+0x41): undefined reference to `wmove'
ncurses is the latest as per the ubuntu (when I do apt-get install lib...", it is telling that installed one is the latest)
I am using ubuntu 11.10 64-bit PC to build the kernel
Posted on Mar 20, 2012
Photo Vincent Randal
Member since Apr 25, 2011
Hello Velibor,

I think you misunderstood Jayson Burak's question on March 15, 2011. It was a year ago, but I don't think he was asking about the home screen. Maybe he was.

I think he was asking for proper procedure for packaging a newly built kernel into an image that can be installed on a real device - not in the emulator.

Your article is good, but maybe the process for building the kernel from source needs updating. And then once you have built the kernel how do you install it on a real physical device like a phone or a tablet?

Vincent Randal
Longmont, CO
Posted on Jun 19, 2012
Photo Carlo Lentini
Member since Jun 19, 2012
Sorry I am new in matters of ROM and Kernel.

I have a Atrix MB860 with fingerprint and like to patch the kernel (currently I on the phone) and thought I'd fill in the following ROM and replace the kernel with this: 20EMEA/4.5.2A-74_OLE-20 /
Choosing kernel_tegra from the list.

I am using a mac pro 10.7.4
And 'the right way? Or do you recommend another way? Is there a guide?
I'm in trouble you help me?

Posted on Jun 29, 2012
Photo Velibor Cakarevic
Enofon AB
Member since Nov 18, 2008
True it needs updating. I have to find some timeslot for that.

Otherwise when flashing the kernel images it can be done by using fastboot. In order to do that you need to set the device in fastboot mode. Various vendors have various ways. Due to NDA I cannot say how this is done for each vendor. Sorry for that.

Regarding adding kernel modules they can be pushed into the device adb push 'modulename.ko'. Yes I root the devices when developing. Then you can add the kernel modules in the kernel by the command insmod 'modulename.ko'
Posted on Sep 6, 2012
Photo yp_1981 yp_1981
Member since Sep 6, 2012
Hi I want to download the android kernel2.6.32 (froyo). Can anyone tell me how to download the tar file for the same?
Posted on Nov 5, 2014
Photo Shivam Singh
Member since Nov 5, 2014
Can you please tell me how to make own config file or source as mtk don't release sources.. But i have sources of my mtk device but the device from where i got mtk sources is android 4.4.4 and my is 4.4.2 please tell me what are the changes i have to do to make own sources?