Attend XDA's Second Annual Developer Conference, XDA:DevCon 2014!
5,732,073 Members 40,732 Now Online
XDA Developers Android and Mobile Development Forum

[Tutorial] How to compile a kernel module outside the kernel

Tip us?
 
viulian
Old
(Last edited by viulian; 26th August 2011 at 11:40 PM.)
#1  
Recognized Developer - OP
Thanks Meter 371
Posts: 394
Join Date: Apr 2011

 
DONATE TO ME
Default [Tutorial] How to compile a kernel module outside the kernel

I've decided to make a short tutorial and present the way I compile kernel modules (outside the kernel sources).

I've built few kernel modules (governors - ineractive and smartass, cifs, nls, etc) and I started receiving private messages asking how I did it.

For kernel modules that come with the kernel itself - cifs / tun for example - they just work if you compile the kernel and activate correct config parameters.
Some other modules (such as the smartass governor that doesn't come with the kernel) you compile outside the kernel source. However they require changes since kernel does not export the symbols the module needs to use - so you have to know what k_all_syms are needed, grab them from the phone and update the kernel module.

So there will be changes there. However, the main steps are:

a) follow tutorials to get the kernel / android ndk to compile. People seem able to do this.
b) then take the module you want (For example cpufreq_smartass.c from here: http://pastebin.com/rR4QUCrk ) and copy it in a new folder on the disk.
c) create a Makefile like the one below, but with your paths of course:

Code:
KERNEL_DIR=/home/viulian/android_platform/kernel-2.1.A.0.435/kernel

obj-m := cpufreq_smartass.o
PWD := $(shell pwd)
default:
        $(MAKE) ARCH=arm CROSS_COMPILE=/home/viulian/android_platform/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules
clean:
        $(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) clean
d) execute make

Of course, the module source needs to be adjusted as you need to put in the frequencies, and also update the k_all_syms pointers .. But you can retrieve them from /proc/kallsyms on the device itself - just look for the method name, and use the address you see in the log.

If you still can't get it to compile, try to compile a very basic hello_world kernel module. I used the code below when testing:

Code:
#include <linux/module.h>  /* Needed by all modules */
#include <linux/kernel.h>  /* Needed for KERN_ALERT */

MODULE_LICENSE("GPL");
MODULE_AUTHOR("viulian, 2011");
MODULE_DESCRIPTION("Demo module for X10i");

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

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


void cleanup_module(void)
{
  printk(KERN_ALERT "Goodbye world 1.\n");
}
It is not perfect, but if you manage to insmod-it and check dmesg, you will see "Hello world" written there.

One more thing, linux kernel is fussy about the module versions. Even if nothing is changed between two kernel versions related to what a module needs, is enough a small difference in module's modinfo value to make the kernel to refuse the module.

For this, you need to trick your local kernel and adjust EXTRAVERSION value in kernel's main Makefile to have the exact version of the one on the device:

In X10 stock kernel (GB 2.3.3 release), the kernel version is 2.6.29-00054-g5f01537 visible in phone settings.

This means that the kernel on the phone will only accept modules that are compiled for that exact version. But the kernel version is just a string in the module .ko, so is a string comparison - the module might work perfectly, but is not loaded.
There is luck though, the string value comes from a define in kernel's Makefile, which you can change before you compile!

The Makefile in the kernel you are going to use to build the module will have to include these lines at the top:

Code:
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 29
EXTRAVERSION = -00054-g5f01537
Other than that, it should work .. Expect phone reboots and difficulty to debug if stuff goes wrong. Android kernel doesn't come with syslog functionality, kernel prints are found in /proc/kmsg. Dmesg works, but you can't execute if if phone reboots.
I usually had to keep another adb shell opening with 'cat /proc/kmsg' which showed as much as possible from the module's outputs.

Happy compiling on your risk!
The Following 22 Users Say Thank You to viulian For This Useful Post: [ Click to Expand ]
 
denzel09
Old
#2  
denzel09's Avatar
Senior Member
Thanks Meter 666
Posts: 3,201
Join Date: Jun 2009
Location: Venezia
Good

Sent from my GT-S5570 using Tapatalk
 
fabricioemmerick
Old
#3  
Member
Thanks Meter 10
Posts: 75
Join Date: Feb 2011
Location: NY
Nice really nice.

Anyone help me.have someone who could compile the linux bluetooth modules please? Iam noob in linux

http://www.multiupload.com/58OPISAYNH
 
fabricioemmerick
Old
#4  
Member
Thanks Meter 10
Posts: 75
Join Date: Feb 2011
Location: NY
Anyone please can make a video tutorial?
 
Mr.Wrong
Old
#5  
Member
Thanks Meter 3
Posts: 32
Join Date: Oct 2011
Location: Spain
That's really nice of you for sharing this.
 
fabricioemmerick
Old
#6  
Member
Thanks Meter 10
Posts: 75
Join Date: Feb 2011
Location: NY
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 .
http://developer.android.com/sdk/ndk/index.html
Download and un(zip|tar) the android SDK found here .
http://developer.android.com/sdk/index.html
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.

Code:
$ 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.

Code:
$ cd /path/to/kernel
$ make ARCH=arm CROSS_COMPILE=/path/to/android-ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi- 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:

Code:
obj-m := modulename.o
KDIR := /path/to/kernel
PWD := $(shell pwd)
CCPATH := /path/to/android-ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin
default:
 $(MAKE) ARCH=arm CROSS_COMPILE=$(CCPATH)/arm-linux-androideabi- -C $(KDIR) M=$(PWD) modules
COMPILING AND INSTALLING YOUR MODULE

Code:
$ 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

Code:
$ cd /path/to/android-sdk/
$ ./adb shell
$ su
# insmod /sdcard/modulename.ko


---------- Post added at 07:40 PM ---------- Previous post was at 07:37 PM ----------

IMPORNTANT TOO

Preparing a build environment

To build an Android kernel, you need a cross-compiling toolchain. Theoretically, any will do, provided it targets ARM. I just used the one coming in the Android NDK:

$ wget http://dl.google.com/android/ndk/and...ux-x86.tar.bz2
$ tar -jxf android-ndk-r6b-linux-x86.tar.bz2
$ export ARCH=arm
$ export CROSS_COMPILE=$(pwd)/android-ndk-r6b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-

For the latter, you need to use a directory path containing prefixed versions (such as arm-eabi-gcc orarm-linux-androideabi-gcc), and include the prefix, but not “gcc”.

You will also need the adb tool coming from the Android SDK. You can install it this way:

$ wget http://dl.google.com/android/android...-linux_x86.tgz
$ tar -zxf android-sdk_r12-linux_x86.tgz
$ android-sdk-linux_x86/tools/android update sdk -u -t platform-tool
$ export PATH=$PATH:$(pwd)/android-sdk-linux_x86/platform-tools
The Following 10 Users Say Thank You to fabricioemmerick For This Useful Post: [ Click to Expand ]
 
fabricioemmerick
Old
#7  
Member
Thanks Meter 10
Posts: 75
Join Date: Feb 2011
Location: NY
not yet ((((

Come on, please make video tuto
 
avalon_droid
Old
#8  
Junior Member
Thanks Meter 2
Posts: 8
Join Date: Oct 2011
that's interesting.
Thanks for sharing
 
fabricioemmerick
Old
#9  
Member
Thanks Meter 10
Posts: 75
Join Date: Feb 2011
Location: NY
Any takers to do a video status? Come on people it would be good for newbies like me and many that tme around. When teaching the community grows.
 
hamsterksu
Old
#10  
Junior Member
Thanks Meter 2
Posts: 8
Join Date: Nov 2011
hi
i'm traing to compile module for acer a500.
but i have got an error: Nothing to be done for `default'.

my makefile:
Code:
obj-m += hello.o
KDIR := /home/hamster/android
PWD := $(shell pwd)
CCPATH := /home/hamster/android-ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin
default:
 $(MAKE) ARCH=arm CROSS_COMPILE=$(CCPATH)/arm-linux-androideabi- -C $(KDIR) M=$(PWD) modules
acer kernel code is located in /home/hamster/android

could you help me?

thanks

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes