Archive for kernel modules

Android Kernel module support. Running a simple hello-world kernel module in Android emulator

Posted in Android with tags , , , , on March 21, 2011 by UnixmanLinuxboy

I was playing with android code and suddenly I thought lets have a small exercise of learning android kernel compilation and loading modules in it.
The following are the steps which I did in order to recompile android kernel for my emulator, write a simple hello world module, compile it, push it to emulator and load it.

Read for some fun? Read on.

==============================
Download and compile GingerBread code
==============================

Go to http://source.android.com/source/download.html and download the source code.
I downloaded the gingerbread branch
repo init -u git://android.git.kernel.org/platform/manifest.git -b gingerbread
repo sync
|
|
|
and the usual commands to get your platform code…

Note: These days the android kernel source is removed from platform code.
So I need to download the kernel source too.
I went to http://android.git.kernel.org/?p=kernel/qemu.git;a=shortlog;h=refs/heads/android-goldfish-2.6.29 and downloaded the kernel for emulator.

Now, I compiled the platform code. (source /build/envsetup.sh && lunch 1 && make -j2)
Once the platform is built, I started building the linux kernel.

===========================================
Compile Android kernel with module support
===========================================

Android kernel, by default do not support loadable modules. So I needed to edit some files.
Here is what I did:

1. make ARCH=arm goldfish_defconfig (This will create our .config)
2. Edit the .config file and searched for the line “CONFIG_MODULES”
It was unset for me and the line looked liked this
# CONFIG_MODULES is not set
I changed the line to CONFIG_MODULES=y, saved and closed the file.
3. Now, I fired the command to build the kernel
make ARCH=arm CROSS_COMPILE=~/timepass/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-

Important: Replace “~/timepass/mydroid” with your KERNEL SOURCE TREE
Note: This command might ask for the following
======================================

scripts/kconfig/conf -s arch/arm/Kconfig
*
* Restart config...
*
*
* General setup
*
Prompt for development and/or incomplete code/drivers (EXPERIMENTAL) [Y/n/?] y
Local version - append to kernel release (LOCALVERSION) []
Automatically append version information to the version string (LOCALVERSION_AUTO) [Y/n/?] y
Support for paging of anonymous memory (swap) (SWAP) [Y/n/?] y
System V IPC (SYSVIPC) [Y/n/?] y
POSIX Message Queues (POSIX_MQUEUE) [N/y/?] n
BSD Process Accounting (BSD_PROCESS_ACCT) [N/y/?] n
Export task/process statistics through netlink (EXPERIMENTAL) (TASKSTATS) [N/y/?] n
Auditing support (AUDIT) [N/y/?] n
Kernel .config support (IKCONFIG) [Y/n/m/?] y
Enable access to .config through /proc/config.gz (IKCONFIG_PROC) [Y/n/?] y
Kernel log buffer size (16 => 64KB, 17 => 128KB) (LOG_BUF_SHIFT) [16] 16
Group CPU scheduler (GROUP_SCHED) [Y/n/?] y
Group scheduling for SCHED_OTHER (FAIR_GROUP_SCHED) [Y/n] y
Group scheduling for SCHED_RR/FIFO (RT_GROUP_SCHED) [Y/n/?] y
Basis for grouping tasks
1. user id (USER_SCHED)
> 2. Control groups (CGROUP_SCHED)
choice[1-2]: 2
Create deprecated sysfs layout for older userspace tools (SYSFS_DEPRECATED_V2) [N/y/?] n
Kernel->user space relay support (formerly relayfs) (RELAY) [N/y/?] n
Namespaces support (NAMESPACES) [Y/?] y
UTS namespace (UTS_NS) [N/y/?] n
IPC namespace (IPC_NS) [N/y/?] n
User namespace (EXPERIMENTAL) (USER_NS) [N/y/?] n
PID Namespaces (EXPERIMENTAL) (PID_NS) [N/y/?] n
Network namespace (NET_NS) [N/y/?] n
Initial RAM filesystem and RAM disk (initramfs/initrd) support (BLK_DEV_INITRD) [Y/n/?] y
Initramfs source file(s) (INITRAMFS_SOURCE) []
Optimize for size (CC_OPTIMIZE_FOR_SIZE) [Y/n/?] y
Default panic timeout (PANIC_TIMEOUT) [0] 0
Enable the Anonymous Shared Memory Subsystem (ASHMEM) [Y/n/?] y
Disable heap randomization (COMPAT_BRK) [Y/n/?] y
Choose SLAB allocator
> 1. SLAB (SLAB)
2. SLUB (Unqueued Allocator) (SLUB)
choice[1-2?]: 1
Profiling support (EXPERIMENTAL) (PROFILING) [N/y/?] n
Kprobes (KPROBES) [N/y/?] (NEW) ---------- I said N here
*
* Enable loadable module support
*
Enable loadable module support (MODULES) [Y/n/?] y
Forced module loading (MODULE_FORCE_LOAD) [N/y/?] (NEW) y
Forced module unloading (MODULE_FORCE_UNLOAD) [N/y/?] (NEW) y
Module versioning support (MODVERSIONS) [N/y/?] (NEW) y
Source checksum for all modules (MODULE_SRCVERSION_ALL) [N/y/?] (NEW) y
*
* Memory Technology Device (MTD) support
*
Memory Technology Device (MTD) support (MTD) [Y/n/m/?] y
Debugging (MTD_DEBUG) [N/y/?] n
MTD concatenating support (MTD_CONCAT) [N/m/y/?] n
MTD partitioning support (MTD_PARTITIONS) [N/y/?] n
MTD tests support (MTD_TESTS) [N/m/?] (NEW) n
*
* User Modules And Translation Layers
*
Direct char device access to MTD devices (MTD_CHAR) [Y/n/m/?] y
Common interface to block layer for MTD 'translation layers' (MTD_BLKDEVS) [Y] y
Caching block device access to MTD devices (MTD_BLOCK) [Y/n/m/?] y
FTL (Flash Translation Layer) support (FTL) [N/m/y/?] n
NFTL (NAND Flash Translation Layer) support (NFTL) [N/m/y/?] n
INFTL (Inverse NAND Flash Translation Layer) support (INFTL) [N/m/y/?] n
Resident Flash Disk (Flash Translation Layer) support (RFD_FTL) [N/m/y/?] n
NAND SSFDC (SmartMedia) read only translation layer (SSFDC) [N/m/y/?] n
Log panic/oops to an MTD buffer (MTD_OOPS) [N/m/y/?] n
*
* Meilhaus support
*
Meilhaus support (MEILHAUS) [N/m/?] (NEW) n
*
* Staging drivers
*
Staging drivers (STAGING) [Y/n/?] y
Exclude Staging drivers from being built (STAGING_EXCLUDE_BUILD) [N/y/?] n
Line Echo Canceller support (ECHO) [N/m/y/?] n
Data Acquision support (comedi) (COMEDI) [N/m/?] (NEW) n
*
* Cryptographic API
*
Cryptographic API (CRYPTO) [Y/?] y
*
* Crypto core or helper
*
FIPS 200 compliance (CRYPTO_FIPS) [N/y/?] n
Cryptographic algorithm manager (CRYPTO_MANAGER) [Y/?] y
GF(2^128) multiplication functions (EXPERIMENTAL) (CRYPTO_GF128MUL) [N/m/y/?] n
Null algorithms (CRYPTO_NULL) [N/m/y/?] n
Software async crypto daemon (CRYPTO_CRYPTD) [N/m/y/?] n
Authenc support (CRYPTO_AUTHENC) [Y/?] y
Testing module (CRYPTO_TEST) [N/m/?] (NEW) n
*
* Authenticated Encryption with Associated Data
*
CCM support (CRYPTO_CCM) [N/m/y/?] n
GCM/GMAC support (CRYPTO_GCM) [N/m/y/?] n
Sequence Number IV Generator (CRYPTO_SEQIV) [N/m/y/?] n

================================================
Once I answered, the compilation continued and now I had a zImage of kernel with loadble module support.

===========================================
Write and compile a simple hello-world module
===========================================

At this point I have kernel with module support and compiled platform. So without much ado I fired up the emulator.


export ANDROID_PRODUCT_OUT=~/mydroid/out/
$ ./emulator -system ~/mydroid/out/target/product/generic/system.img -kernel ~/goldfish_kernel/arch/arm/boot/zImage -data ~/mydroid/out/target/product/generic/userdata.img -ramdisk ~/mydroid/out/target/product/generic/ramdisk.img -skindir ~/mydroid/sdk/emulator/skins/ -skin HVGA -verbose -show-kernel

Once emulator is up, I wrote the simple “Hello-world” module: Source is as follows:


1 #include"linux/module.h"
2 #include"linux/kernel.h"
3//replace the "" with angular brackets
4 int init_module(void)
5 {
6 printk(KERN_INFO "Hello android kernel...\n");
7 return 0;
8 }
9
10 void cleanup_module(void)
11 {
12 printk(KERN_INFO "Goodbye android kernel...\n");
13 }
14

I saved the file as android_module.c

Kernel modules as we know have to be compiled slightly differently than traditional programs.
My makefile for this simple module is as follows:


1 obj-m += android_module.o
2
3 all:
4 make -C /home/user/android_goldfish_kernel/goldfish-2.6.29/ M=$(PWD) modules
5
6 clean:
7
8 make -C /home/user/android_goldfish_kernel/goldfish-2.6.29/ M=$(PWD) clean

Now we are ready to compile our android kernel module


CROSS_COMPILE=/home/user/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm make

Once compilation is done, I got android_module.ko

===========================================
Push the module inside emulator and execute it
===========================================

I pushed the newly build module inside emulator by:


adb push android_module.ko /data/local

Now that my module is inside the emulator which was already running kernel with module support, I opened a shell by:

adb shell

Inside this emulator shell prompt, I navigated to /data/local and executed
insmod android_module.ko
rmmod android_module
dmesg

The result is

android_module: module license 'unspecified' taints kernel.
Hello android kernel...
Goodbye android kernel...

If you have any doubt, please feel free to drop a comment here 🙂