Sunday, 2 May 2010

How to BUILD the LINUX KERNEL for the ANDROID EMULATOR (Eclair version)

DOWNLOAD THE KERNEL SOURCE CODE


First we download the kernel source code from https://android.googlesource.com

Within that page there are kernels for other platforms too. We choose to download kernel/goldfish project from there.

$ git clone https://android.googlesource.com/kernel/goldfish

A goldfish directory appears:
$ cd goldfish
This directory does not contain any source code in it.

We check which branch we have downloaded:
$ git branch
it shows * master , not the one we are searching for:

To list all remote available branches:
$ git branch -r
or
$ git remote show origin
origin/HEAD -> origin/master
  origin/android-goldfish-2.6.29
  origin/android-goldfish-3.4
  origin/linux-goldfish-3.0-wip
  origin/master


What does goldfish mean? (from android-kernel mail list)
Goldfish is the kernel hacked branch that supports the qemu based arm emulator for android, so it is the one we need.

Download GOLDFISH kernel version
Choose the version that suits you.
$ git checkout --track -b android-goldfish-2.6.29 origin/android-goldfish-2.6.29
$ git branch
* android-goldfish-2.6.29
  master


RUNNING THE EMULATOR


Within this link we will find how to get the android emulator, and launch it.
Building Android in Debian Sid

Showing the kernel version running in the emulator
$ adb shell
# cat /proc/version
Linux version 2.6.29-00261-g0097074 (digit@digit.mtv.corp.google.com) (gcc version 4.4.0 (GCC) ) #14 Tue Feb 2 15:49:02 PST 2010


OBTAINING KERNEL CONFIGURATION


We are going to obtain the kernel configuration .config file from within our running emulator.

$ cd /path/to/goldfish # we enter in the kernel source directory.
$ adb pull /proc/config.gz . # get compressed .config file from the emulator.

$ gunzip config.gz # uncompress it.
$ cp config .config # rename it into .config

Now you can edit .config file the way it suits you the most.


BUILDING AND COMPILING THE KERNEL


CROSS_COMPILE environment variable stores the path to the arm cross compiling toolchain. I use the one which comes with android source code.

$ ARCH=arm CROSS_COMPILE=/path/to/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- make

Executing make will build the kernel.

Last lines will show:
Kernel: arch/arm/boot/Image is ready
Kernel: arch/arm/boot/zImage is ready


So we have obtained Image and zImage kernel binary files.


RUN THE EMULATOR USING THE NEW COMPILED KERNEL IMAGE


We need -kernel option:
$ emulator -kernel /path/to/goldfish/arch/arm/boot/zImage -show-kernel -verbose

We can check now the kernel version:
$ adb shell
# cat /proc/version
Linux version 2.6.29-00262-gb0d93fb (user@myPC) (gcc version 4.4.0 (GCC) ) #1 Sun May 2 14:27:31 CEST 2010


If we do not specify kernel option it usually uses the prebuilt one:
$ emulator -show-kernel -verbose
emulator: argv[01] = "-kernel"
emulator: argv[02] = "/path/to/mydroid/prebuilt/android-arm/kernel/kernel-qemu"


ACTIVATING MODULE LOADING SUPPORT IN THE KERNEL


Module loading support is previously disabled in the kernel, if we want to load modules in the kernel we have to enable it:

edit .config file and set:
CONFIG_MODULES=y

$ ARCH=arm CROSS_COMPILE=/path/to/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- make

I am asked about some options when executing make. I ask yes for module related options.

After compiling I see several modules have been built.

MODPOST 6 modules
CC      drivers/video/fb_sys_fops.mod.o
LD [M]  drivers/video/fb_sys_fops.ko
CC      drivers/video/syscopyarea.mod.o
LD [M]  drivers/video/syscopyarea.ko
CC      drivers/video/sysfillrect.mod.o
LD [M]  drivers/video/sysfillrect.ko
CC      drivers/video/sysimgblt.mod.o
LD [M]  drivers/video/sysimgblt.ko
CC      drivers/video/vfb.mod.o
LD [M]  drivers/video/vfb.ko


We can upload the modules in the emulator and install them:
$ adb push drivers/video/fb_sys_fops.ko /data
$ adb shell
# insmod /data/fb_sys_fops.ko


REFERENCE


http://www.cianer.com/androidg1/28-building-android-kernel-images


YOU MAY ALSO BE INTERESTED IN:


Building Android in Debian Sid

25 comentarios:

corteplaneta said...

EXCELLENT guide, though it took me forever to find.

Only one quick thing I'd like to comment on--when performing these steps on an Android Virtual Device, you'll definitely run into some issues with the loop device.

I was getting something along the lines of "file not found," just getting thrown back to mount's usage, etc.

To fix this, I did a bit of googling & found these (extra) steps which helped me get this working on the AVD:

bash-3.2# mknod /dev/loop7 b 7 0
bash-3.2# losetup /dev/loop7 debian.img
losetup /dev/block/loop7 /sdcard/debian/debian.img
mount -t ext2 -o noatime,nodiratime,sync /dev/block/loop7 /sdcard/debian/mnt

Source: http://forum.xda-developers.com/showthread.php?t=396782&page=748

Overall, thanks a lot!

Vicente Hernando said...

Hi corteplaneta,

As a simpler solution, I set ANDROID_PRODUCT_OUT environment variable, instead of creating an Android Virtual Device.
Building Android in Debian Sid


Thank you for the AVD point!

Kari said...

Hello,

Thanks for the great guide! I was wondering if you know if there is a way to compile a newer version of the Android kernel (2.6.32 or 2.6.35) to use with the emulator. I have been using the goldfish 2.6.29 branch, but I need some of the changes to the Linux kernel that occurred in version 2.6.31, and I would like to test some things using the emulator. Do you have any ideas of what I could do? Or, do you know if there will be a newer release of goldfish soon?

Thanks!

Vicente Hernando said...

Hi Kari,

I think there is right now (july 2010) no goldfish kernel version newer than 2.6.29.

If you need newer features appearing in 2.6.31 version, you could try to extract patches from it, and apply them into your 2.6.29 goldfish version.

Anyway, just to be sure there is no 2.6.31 goldfish version, you could ask at Android kernel mail list

HTH,
Vicente.

Victor said...

Great guide. How would you build the Linux kernel for an Android device itself? Can you use the same Linux source (goldfish)?

Thanks!

Vicente Hernando said...

Hi Victor,

for real devices you should not use goldfish source code. You should go instead to http://android.git.kernel.org/ and get the kernel source code that suits your real device.

Narseo Vallina-Rodriguez said...

Hi,

I found this tutorial very useful but I had to change some things (for instance I couldn't load the emulator without specifying a virtual device with -adv @foo).

Do you know the way to do it without using any particular avd? Do you know the way to load in the emulator both a new kernel and a platform (i.e. all the android services and dalvik) that has been modified?

Cheers,

Vicente Hernando said...

Hi Narseo,

within this article Building Android in Debian Sid you will read how to use ANDROID_PRODUCT_OUT variable. This way
you can specify where the android platform files are.

Also you could use -kernel option when running emulator to specify which kernel you want to load.

For a list of emulator command line options:
$ ./emulator -help

Anh Nguyen said...

Very clear guide!
But now I want to replace the kernel in my HTC smartphone by my new custom kernel. So, could you show me the way to do that?

Many thanks!

Vicente Hernando said...

Hello Anh Nguyen,

I have not any HTC phone to test, so I cannot assure you anything.

However this url may help you:
http://htcevohacks.com/htc-evo-hacks/how-to-build-your-own-htc-evo-4g-android-kernel/

PhosphoricX said...

Thanks so much, this is really helpful to me!

Patrizio said...

I followed a route similar to the one you made. Anyway my modules are not SYSV compliant. I do not know why

Immmling said...

This is a very useful post! I just tried it. The only issue is at the moment when I try to start the emulator after compiling my kernel, it seems to stall at:

emulator: ping command: /home/android-sdk-linux_x86/tools/ddms ping emulator standalone

Any idea?

Anonymous said...

it's good guide, thank you.

However I cannot get the zImage startup in emulator,after the commend "emulator -avd XXX /.../zImage"

There is no error.
Is anyone the same like me?

Anonymous said...

Same here, it just hangs here:

emulator: control console listening on port 5554, ADB on port 5555
emulator: sent '0012host:emulator:5555' to ADB server
emulator: ping program: /home/mfisch/Projects/android-sdk-linux/tools/ddms
emulator: ping command: /home/mfisch/Projects/android-sdk-linux/tools/ddms ping emulator 20.0.1.0 "ATI Technologies Inc." "AMD Radeon HD 7400M Series" "4.2.11627 Compatibility Profile Context"

Running the other kernel, it starts uncompressing the kernel.

Anonymous said...

upon running this command

git clone git://android.git.kernel.org/kernel/common

gettin error like this

Initialized empty Git repository in /home/user/common/.git/
android.git.kernel.org[0: 149.20.4.77]: errno=Connection refused
fatal: unable to connect a socket (Connection refused)

please can anybody help..

Vicente Hernando said...

Hi 09:54 anonymous

they seem to have moved the repository to another location.

Let's try this other location:
git clone https://android.googlesource.com/kernel/common

Thanks for pointing that.

Vicente Hernando said...

Hello 17 and 26 sept. anonymous,

to get more clues about what is happening to you, you could add "-debug all -verbose -show-kernel" options when launching the emulator.

Adornment said...

Hi,

Thanks for the stepwise info, but when I try to ./adb pull /proc/config.gz

it gives me the following error :
remote object '/proc/config.gz' does not exist

Do you have any inputs why its missing ? Please help me sort this out.
Thanks,
Neha

Adornment said...

Hi,

Thank you for the detailed steps to build kernel source but I'm stuck on ./adb pull /proc/config.gz

It gives me an error : remote object '/proc/config.gz' does not exist

Could you please help me sort this out.
Thanks for your help,
Neha

Vicente Hernando said...

Hi Neha,

/proc/config.gz file only appears if kernel has been configured with CONFIG_PROC option.

I am afraid, you will have to search the configuration in other place, or guess it reading dmesg log.

Adornment said...

Thanks Vicente for your help. What exactly do I need to look for ? I downloaded the kernel source for my Motorola Android phone and searched for config in it but did not find any files. I'm trying to build the kernel source of my phone using the phones config.gz but i'm not able to find it. What do I do next ?

-Neha

Vicente Hernando said...

Hello Neha,

you could try to use a config.gz file from other model phone, or use default configuration, or try to guess it.

Alex Perez said...

I've compiled a basic hello world Android kernel module

#include /* Needed by all modules */
#include /* Needed for KERN_INFO */
#include /* Needed for the macros */

static int hello3_data __initdata = 3;

static int __init hello_3_init(void)
{
printk(KERN_INFO "Hello, world %d\n", hello3_data);
return 0;
}

static void __exit hello_3_exit(void)
{
printk(KERN_INFO "Goodbye, world 3\n");
}

module_init(hello_3_init);
module_exit(hello_3_exit);
and written the following in the Makefile :

VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 29
EXTRAVERSION =
obj-m += hello_3.o
KDIR=/home/aniket/beproject/htconev/android/goldfish
PWD := $(shell pwd)
all:
make -C $(KDIR) ARCH=arm CROSS_COMPILE=/home/aniket/beproject/android/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/arm-linux-androideabi- SUBDIRS=$(PWD) modules

clean:
make -C $(KDIR) ARCH=arm CROSS_COMPILE=/home/aniket/beproject/android/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/arm-linux-androideabi- SUBDIRS=$(PWD) clean
However after running make and pushing it to the Android device it gives me an error :

insmod: init_module _.ko failed (Exec format error)
I got rid of that error using

make CFLAGS_MODULE=-fno-pic
while running make against the kernel module however after using dmesg it says:

hello_3: module license 'unspecified' taints kernel.
hello_3: unknown relocation: 27
hello_3: no version for "magic" found: kernel tainted.

Can you please tell me where I've gone wrong ?

Vicente Hernando said...

Hello Alex,

just a guess: I think the version of the kernel sources you compiled the module against and the running kernel do not match.

May this thread give you some clues (although not exactly the same problem)
http://www.spinics.net/lists/newbies/msg13664.html