Wednesday, January 5, 2011

Guide to Compiling Custom Kernel Modules in Android

I've spent the better part of today trying to figure out how to compile and load a custom kernel modules in android to aid me in my research.  It has been in entirely frustrating experience, as there is almost no documentation on the topic that I can find.  Below you will find my attempt at a guide.  Hopefully this will help save someone else the hassle.

PREREQUISITES

Disclaimer:  This list may be incomplete, since I've not tried it on a fresh install. Please let me know if I've missed anything.
  • Install the general android prereqs found here. 
  • Download and un(zip|tar) the android NDK found here.
  • Download and un(zip|tar) the android SDK found here.
  • Download and untar the kernel source for your device.  This can usually be found on the website of your device manufacturer or by a quick Google search.
  • Root your phone.  In order to run custom kernel modules, you must have a rooted phone.
  • Plug your phone into your computer.

PREPARING YOUR KERNEL SOURCE

First we must retrieve and copy the kernel config from our device.
$ cd /path/to/android-sdk/tools
$ ./adk pull /proc/config.gz
$ gunzip ./config.gz
$ cp config /path/to/kernel/.config
Next we have to prepare our kernel source for our module.
$ cd /path/to/kernel
$ make ARCH=arm CROSS_COMPILE=/path/to/android-ndk/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86/bin/arm-eabi- modules_prepare
PREPARING YOUR MODULE FOR COMPILATION

We need to create a Makefile to cross-compile our kernel module.  The contents of your Makefile should be similar to the following:
obj-m := modulename.o
KDIR := /path/to/kernel
PWD := $(shell pwd)
CCPATH := /path/to/android-ndk/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86/bin
default:
$(MAKE) ARCH=arm CROSS_COMPILE=$(CCPATH)/arm-eabi- -C $(KDIR) M=$(PWD) modules
COMPILING AND INSTALLING YOUR MODULE
$ cd /path/to/module/src
$ make
$ cd /path/to/android-sdk/tools/
$ ./adb push /path/to/module/src/modulename.ko /sdcard/modulename.ko
RUNNING YOUR MODULE
$ cd /path/to/android-sdk/
$ ./adb shell
$ su
# insmod /sdcard/modulename.ko
CONCLUSION

Ineviditibly you'll run into some errors that you will need to sort out, as I did with both my droid 2 and evo devices.  Feel free to post in the comments if you run into any major problems, and I'll try my best to help you out.

6 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. When you say /path/to/kernel, I am assuming that it is the path in the /out/....//... directory. Am I right? If so, for some reason, there is no kernel directory in there. Also, it gives me an error saying that there is no rule to prepare for 'modules_prepare'. I am not sure if I am missing any step here. Do you know why this could be happening?

    ReplyDelete
  3. It should read /path/to/kernel/source. I have to update this post to make it more precise. You need to download the kernel source from the phone's manufacturer.

    I'll update the post to contain new information and troubleshooting as soon as I can.

    ReplyDelete
  4. Is that a typo? "./adk pull /proc/config.gz" Should be "./adb"?

    -Brendan ;)

    ReplyDelete
  5. Hello.
    I have a problem. I found this "source code" :
    https://github.com/vurrut/android_ke...ockchip_rk2918
    or here
    https://github.com/yatto/Smartpad-810c-Kernel-3.0.8

    But does not contain the "source code" of the module touch my tablet .

    How do I add it to the compilation?

    I have compiled the module apart and also I have the "source code".

    Thank

    ReplyDelete
  6. Hi Joe,

    I'm trying to compile the kernel source and when I use ./adb pull /proc/config.gz I get the following error :
    remote object '/proc/config.gz' does not exist

    Do you have any info about this ? Please help.

    Thanks !

    ReplyDelete