The latest Android 2.2 Emulator from the Android SDK does not support loadable kernel modules. Therefore, the first order of business is to compile a new kernel for the emulator that allows dynamic kernel module loading.
Prepare the Build Enviornment
The easiest way to compile a Linux kernel for Android is to use build scripts from Android itself. Refer to my previous blog on how to check out a Android platform build. From the root of the platform source tree, run:
$. build/envsetup.sh
$lunch 1
Check-out the Kernel Source For the Emulator
Change to a new directory and check out the Linux kernel source for the Emulator. Note that we must check out the version that matches our emulator because of Linux kernel compatibility rules. See the Guide for details. In this example, we use the Android 2.2 emulator from the official SDK. This emulator uses kernel version 2.6.29. You can find this version number in Settings or from /proc/version in the adb shell.
$ git clone git://android.git.kernel.org/kernel/msm.git .
$ git checkout --track -b my-goldfish-2.6.29 remotes/origin/android-goldfish-2.6.29
Configure the Kernel Source
The easiest method to configure the kernel source is to use the configuration from a running emulator:
$ adb pull /proc/config.gz
$ gunzip config.gz
$ mv config .config
Now edit the .config file and enable the kernel module feature:
CONFIG_MODULES=y
Save the file and proceed to build:
$ export ARCH=arm
$ export CROSS_COMPILE=arm-eabi-
$ make
Now we have a new kernel that we can use to load our kernel modules.
Compile External Kernel Modules
Create a new directory outside the kernel source tree. Then create a hello-3.c file and copy-n-paste the source code from the Guide. Next, create a Makefile to use our own kernel source tree:
KERNELSRC=/mydroid/kernel
all:
make -C $(KERNELSRC) M=$(PWD) modules
clean:
make -C $(KERNELSRC) M=$(PWD) clean
Then run make:
$ make
It will create a "hello-3.ko" file after completion. This is the kernel module that we will use on our Android. If the kernel source was not configured with "CONFIG_MODULES=y", the compiler would usually throw up an error like this:
error: variable '__this_module' has initializer but incomplete type
Store the Kernel Module onto Android
We first need to use the Android SDK to create an AVD. In this example, we set the target of the AVD to 2.2. We then start this AVD with the emulator pointing to our newly built kernel:
$ emulator -kernel /mydroid/kernel/arch/arm/boot/zImage -avd myavd
We can store our kernel module anywhere that is writeable on Android. No need to "repack" the system image as some on the web has suggested. The system image from the SDK is not writeable so we will put our file on the user data partition, which is always writeable.
$ adb push /mymodule/hello-3.ko /data/hello-3.ko
Load the Kernel Module
Run the insmod command in the adb shell mode to load our module:
# cd /data
# insmod hello-3.ko
If there is no error, you can verify the new module using the lsmod command:
# lsmod
hello_3 1004 0 - Live 0xbf000000 (P)
You can also verify the module output in kmsg:
# cat /proc/kmsg
<4>hello_3: module license 'unspecified' taints kernel.
<6>Hello, world 3
Congratulations! You are now an Android kernel programmer. Use your power wisely.
nice article. thanks
ReplyDeleteI have tried using this approach but when I run make, I get no .ko file. The output of make lists all the modules that were built but mine isn't one of them.
ReplyDeleteAny thoughts?
Yeah I ran into the same problem. Make sure you grab the source code to the kernel as well:
Deletehttps://android.googlesource.com/
I choose /devices/generic/goldfish - for emulator