Tuesday, July 2, 2013

Writing and testing Linux kernel modules for Android

We compiled and installed some modules in Linux kernel in previous post. Here I'm going to write my own kernel modules and do the same. I'm stilling learning about this and I was able to write and test a hello world kernel module on my phone.

Phone kernel : Linux 2.6.32.60-Kappa1.6
PC O/S : Ubuntu 13.04 32bit
Cross compiler toolchain : Linaro GCC 4.7-2013.01

Prerequisite

1) Check for your kernel info using "uname -a" on either terminal emulator or ADB (use "adb shell" and run it).
My result:  Linux version 2.6.32.60-Kappa1.6 (Ka@Kappa) (gcc version 4.7.3 20130102 (prerelease) (Linaro GCC 4.7-2013.01) ) #94 PREEMPT Sun Apr 28 23:46:13 CEST 2013

2) Get the appropriate kernel source for your kernel. I got 2.6.32.60-Kappa1.6 kernel source from a GIT host using, (If you don't have git installed, you can install it by sudo apt-get install git)
git clone https://github.com/KaSt/Kappa.git
Now my kernel source is at /home/buddika/kernel/Kappa/

3) Download the appropriate cross-compiler toolchain, I'm using Linaro GCC 4.7-2013.01 toolchain.

4) Extract toolchain to somewhere, I extracted it to, /home/buddika/linaro

Coding

I made a directory for my coding as /home/buddika/modules
Please edit these codes to suite your environment. :)

1) hello.c

/* 
 *  hello-1.c - The simplest kernel module.
 */
#include <linux/module.h>    /* Needed by all modules */
#include <linux/kernel.h>    /* Needed for KERN_INFO */

int init_module(void)
{
    printk(KERN_INFO "Hello world 1.\n");

    /*
     * A non 0 return means init_module failed; module can't be loaded.
     */
    return 0;
}

void cleanup_module(void)
{
    printk(KERN_INFO "Goodbye world 1.\n");
}

2) Makefile

VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 32
EXTRAVERSION = .60Kappa-1.6

KERNEL_DIR=/home/buddika/kernel/Kappa/

obj-m := hello.o
PWD := $(shell pwd)
default:
    $(MAKE) ARCH=arm CROSS_COMPILE=/home/buddika/linaro/bin/arm-linux-gnueabihf- -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules
clean:
    $(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) clean

Building:

Now in console execute following commands,

cd /home/buddika/modules
make

Now the kernel module hello.ko will be built at /home/buddika/modules

Testing:

I copied /home/buddika/modules/hello.ko my sdcard at /sdcard/mymod using (please make /sdcard/mymod directory before doing this)
adb push /home/buddika/modules/hello.ko /sdcard/mymod/

You can log into phone shell using adb shell and get root access using su at the shell.

Let's load the module using,

insmod /sdcard/mymod/hello.ko

You can check whether the module is loaded by using lsmod and check for output


root@android:/ # lsmod
Module                  Size  Used by
hello                    610  0




Run dmesg and check for line like this.If so you have written your first kernel module and loaded it successfully. :)

<6>[29913.944610] Hello world 1.

References:
1) The Linux Kernel Module Programming Guide  
2) viulian's guide on xda-developers.com