Android - Kernel, Modules, and the Emulator

After cumbersome reading, a bunch of not so good howtos, and a lot of plain wrong information I finally got it right.
This will explain how I got the following to work:
  1. Getting the toolchain for building an Android kernel
  2. Getting the correct kernel to use with the emulator
  3. Compiling the kernel for the emulator
  4. Compiling a loadable kernel module (LKM) for the emulator

1. Getting the toolchain for building an Android kernel

The first thing is to the the Android NDK from http://developer.android.com/sdk/ndk/index.html and place it somewhere. For me its:
~/android-sdks/android-ndk-r4

Ads by Google
 

2. Getting the correct kernel to use with the emulator

Since I did not want to fetch the extra large build environment for the whole Android platform, I only checked out the kernel the can be used with the emulator. It is called Goldfish.
So you need to checkout the kernel using
git clone git://android.git.kernel.org/kernel/common.git
After that you need to checkout the branch for Goldfish
git checkout -t origin/android-goldfish-2.6.29 -b goldfish
Take a look at all the branches to see the remote branches. I got confused since the master branch was actually empty.
So now I have the Goldfish kernel residing at
~/android-sdks/kernelSource/goldfish

2. Compiling the kernel for the emulator

The first thing to do is to get a .config for the kernel to be compiled. You can either pull the one from the running emulator extract it, and copy it to the kernel like
adb pull /proc/config.gz

gunzip config.gz && cp config ~/android-sdks/kernelSource/goldfish/.config
or (which worked better for me) running
make ARCH=arm goldfish_defconfig
from the goldfish kernel source.
This is the preparation which is needed. Now this is my way to compile the kernel from ~/android-sdks/kernelSource/goldfish
#!/bin/bash
cd goldfish

export CCOMPILER=~/android-sdks/android-ndk-r4/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-

make ARCH=arm CROSS_COMPILE=$CCOMPILER -j`grep 'processor' /proc/cpuinfo | wc -l`
Note that we are using the cross-compilation toolchain provided by the Android NDK in the option CROSS_COMPILE.
Once this is done, we can run the kernel which is now located at
~android-sdks/kernelSource/goldfish/arch/arm/boot/zImage
We can now run the kernel using the emulator of the Android SDK (which needs to be installed) like this:
$WHEREVER_YOUR_EMULATOR_IS -kernel ~android-sdks/kernelSource/goldfish/arch/arm/boot/zImage -show-kernel-verbose -avd Android233 -partition-size 2047
Android233 is my Android Virtual Device (AVD) which I created using the AVD manager from Eclipse. The base AVD config.ini is below:
hw.lcd.density=240
sdcard.size=512M
skin.name=WVGA800
skin.path=platforms/android-10/skins/WVGA800
hw.cpu.arch=arm
abi.type=armeabi
vm.heapSize=24
snapshot.present=true
hw.ramSize=256
image.sysdir.1=platforms/android-10/images/
Note that SDCard is enabled and so are the snapshots which is more convenient for developing.

Ads by Google

4. Compiling a loadable kernel module (LKM) for the emulator

So now that the emulator can run our custom compile kernel, lets compile a corresponding module. The code of the very simple Hello module is like this:
#include   /* Needed by all modules */
#include   /* Needed for KERN_ALERT */

MODULE_LICENSE("GPL");
MODULE_AUTHOR("eeknay, 2012");
MODULE_DESCRIPTION("Demo module");

int init_module(void)
{
	printk("<1>Hello world\n");
	return 0;
}

void cleanup_module(void)
{
	printk(KERN_ALERT "Goodbye world 1.\n");
}
In my case the code resides in ~android-sdks/kernelSource/goldfish/custom_modules/hello. The Makefile for compiling the module form the directory is:
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 29
EXTRAVERSION = -00054-g5f01537

obj-m += hello.o

KDIR=~/android-sdks/kernelSource/goldfish
PWD := $(shell pwd)


default:
	make -C $(KDIR) ARCH=arm CROSS_COMPILE=~/android-sdks/android-ndk-r4/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi- SUBDIRS=$(PWD) modules

clean:
		make -C $(KDIR) ARCH=arm CROSS_COMPILE=~/android-sdks/android-ndk-r4/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi- SUBDIRS=$(PWD) clean
Here it is imporant the the module version number matches the kernel against which it is compiled and after that run.
Before actually compiling the module the kernel source needs to be prepared. This was a crucial step in my attempt to get it working.
Go to the the Goldfish kernel directory and run this:
make ARCH=arm CROSS_COMPILE=~/android-sdks/android-ndk-r4/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi- modules_prepare
Once this is done, you can go ahead an compile the Hello module using the Makefile from above.
Upon completion, we can push the module to the emulator.
adb push hello.ko /sdcard
Now we connect to the emulator using adb shell and load the module like this:
You should see the output of the module in the shell from which you ran the emulator.
If you module did not load, or it did load but you cannot rrmod it, then the following options are disable in the kernel config. Below you can see a working config.
CONFIG_MODULES=y (this needs to be set to allow loading)
# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
  • CONFIG_MODULES needs to be enabled to load modules
  • CONFIG_MODULES_UNLOAD is necessary for unloading modules
  • CONFIG_MODULES_FORCE_UNLOAD yes, you sometimes need the force ;)

Ads by Google

No comments:

Post a Comment

Thank You , For Immediate Assistance Plz Put Email Copy to Deviceporting@gmail.com