Building the Android Kernel
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.git.kernel.org/kernel/common.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
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:
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'
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
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.
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 .
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'  or 'modprobe'  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.
Google has also added some information since I posted this article. Please have a look at the "Android Platform Developer´s Guide" 
In order to help you I would have to be sitting next to you.
root@ubuntu:~/common# ARCH=arm CROSS_COMPILE=~/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- make
make: `include/asm-arm/mach-types.h' is up to date.
SYMLINK include/asm -> include/asm-arm
<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
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!
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.
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]
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
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?
I have a Atrix MB860 with fingerprint and like to patch the kernel (currently 184.108.40.206 I on the phone) and thought I'd fill in the following ROM http://forum.xda-developers.com/showthread.php?t=1326743 and replace the kernel with this:
http://sourceforge.net/projects/atrix.motorola/files/Atrix% 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?
Otherwise when flashing the kernel images it can be done by using fastboot. http://android-dls.com/wiki/index.php?title=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'