Compiling kernel module without exact kernel source - android

I managed to compile my kernel module with a very similar kernel source like my Android device owns, but during the installation i get 'disagrees about version of symbol module_layout' error message, what is an expected behavior.
I picked the binary kernel image from the device and extracted the Module.symvers file. I tried to place the extracted file to the following places:
changed the original one in the similar kernel source's directory
next to my module source code (after compilation it is always emptied /imho because i don't export any symbol/)
After compiling my module, the values from the newly extracted file are still not used. The modulename.mod.c file still contains the original values.
Here is my Makefile for the module:
KERNEL_DIR=~/android/kernels/kernel_3.4.0
obj-m += module.o
PWD := $(shell pwd)
default:
$(MAKE) ARCH=arm CROSS_COMPILE=arm-eabi- -C $(KERNEL_DIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) clean
What am I missing?

Related

How to build Helloword in android custom kernel

insmod: failed to load hello.ko: Function not implemented
during kernel build to logout message like 'hello world', I've got such an error, following steps will reproduce the bug:
1)I downloaded goldfish kernel from git clone https://android.googlesource.com/kernel/goldfish/ -b android-goldfish-3.18
2)also downloaded the toolchain coming with the above repo using git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9
3)I changed directory to goldfish and created the paths mentioned in the documentation (github)
4)then i attempted to build the kernel using this sudo make ARCH=x86_64 CROSS_COMPILE=/home/ana/x86_64-linux-android-4.9-nougat-dev/bin/x86_64-linux-android- in the kernel directory (goldfish) and set LOADABLE_MODULES=y
5)In the next step, I created hello.c file and the Makefile related to it in helloKernel directory.
hello.c
#include<linux/module.h>
#include<linux/init.h>
#include<linux/kernel.h>
MODULE_AUTHOR("Robert P. J. Day");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION("2:1.0") ;
MODULE_DESCRIPTION("You have to start somewhere.");
static int hello_init(void){
printk(KERN_ALERT "Hello TheLittleNaruto it’s your first driver.\n");
return 0;
}
static void hello_exit(void){
printk(KERN_INFO "Goodbye TheLittleNaruto No point in keeping this driv er running.\n");
}
module_init(hello_init);
module_exit(hello_exit);
Makefile
obj-m := hello.o
KERNELDIR := /home/ana/goldfish/
PWD :=$(shell pwd)
ARCH=x86_64
CROSS_COMPILE=/home/ana/x86_64-linux-android-4.9-nougat-dev/bin/x86_64-linux-android-
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld
CFLAGS_MODULE=-fno-pic
modules:
make -C $(KERNELDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules
clean:
rm *.o *.ko *.mod.c *.order *.symvers
in the same directory I created hello.ko with this sudo make ARCH=x86_64 CROSS_COMPILE=/home/ana/x86_64-linux-android-4.9-nougat-dev/bin/x86_64-linux-android-
7)and then i copied hello.ko to android emulator using sudo adb push hello.ko /data/local
8)and then i attempt insmod hello.ko in /data/local
and I get the above-mentioned error, please help me solve this problem. thanks in advance
two things to add in your code
function entry and exit routine
module_init(init_module);
module_exit(cleanup_module);
Let init_module function return 0 rather 1 because 0 means we are good.

Error in loading android kernel module (No symbol version for module_layout)

I am trying to load a kernel module for android.
First, I've download the kernel source code from the target device which MotoG5 from here: https://github.com/MotorolaMobilityLLC/kernel-msm. Also, I've added these files which contain f2fs for compilng the kernel (available here https://github.com/MotorolaMobilityLLC/motorola-kernel) . I was able to compile the kernel using the following commands :
export CROSS_COMPILE=/media/hero/HDD1/android-ndk-r15c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-
export ARCH=arm
make clean && make mrproper
make msm8937-perf_defconfig
make -j4
make modules // to generate Module.symvers which can be used later to compile a kernel module.
Then, I wrote small kernel code as follow :
#include "linux/module.h"
#include "linux/kernel.h"
//replace the "" with angular brackets
int init_module(void)
{
printk(KERN_INFO "Hello android kernel...\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Goodbye android kernel...\n");
}
android_module.c
obj-m += android_module.o
KDIR := /media/hero/HDD1/k3/kmsm/
PWD := $(shell pwd)
ARCH=arm
CROSS_COMPILE=/media/hero/HDD1/android-ndk-r15c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-
all:
make -C $(KDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
Makefile
After that, I was able to compile the kernel successfully with no warning at all. here are some info about the vermagic and file command output for the generated kernel module.
root#root:/hello3# modinfo android_module.ko
filename: /media/hero/HDD1/hello3/android_module.ko
depends:
vermagic: 3.18.31-perf SMP preempt mod_unload modversions ARMv7 p2v8
root#root:/hello3# file android_module.ko
android_module.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=a9bcb514badd8f5799151e0ee4993fd73302175c, with debug_info, not stripped
I compare these info to an existing kernel module in the phone and they match exactly. this is a sample for existing loadable kernel.
modinfo *******.ko
filename: *******.ko
license: GPL
description: Input driver event debug module
author: Vojtech Pavlik <vojtech#ucw.cz>
alias: input:b*v*p*e*-e*k*r*a*m*l*s*f*w*
depends:
intree: Y
vermagic: 3.18.31-perf SMP preempt mod_unload modversions ARMv7 p2v8
file *******.ko
evbug.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=b14c49bf595842f41a31b9a5d0e66bc8523703a8, with debug_info, not stripped
Now. The problem is whenever I load the module I got this message
insmod: failed to load android_module.ko: Exec format error
Also, dmesg show the following :
android_module: no symbol version for module_layout
Please note that some answers online said that I should generate Module.symvers before compiling a kernel module so I did that and I did not encounter any error regarding missing Module.symvers while compiling the kernel module.
Any idea, why this module cannot be load ? please let me know.
Regards,

Can't build hello world kernel module on Android JellyBean

I'm trying to build a simple kernel module on Android JellyBean.
Code:
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_ALERT */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("test");
MODULE_DESCRIPTION("Android ko test");
int init_module(void)
{
printk(KERN_ALERT, "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");
}
Makefile:
obj-m +=hello.o
KERNELDIR ?= ~/android/kernel
PWD := $(shell pwd)
CROSS_COMPILE=~/android/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
ARCH=arm
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) modules
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
Output:
make -C ~/android/kernel M=/home/test/testmod ARCH=arm CROSS_COMPILE=~/android/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- modules
make[1]: Entering directory `/home/test/android/kernel'
ERROR: Kernel configuration is invalid.
include/generated/autoconf.h or include/config/auto.conf are missing.
Run 'make oldconfig && make prepare' on kernel src to fix it.
WARNING: Symbol version dump /home/test/android/kernel/Module.symvers
is missing; modules will have no dependencies and modversions.
CC [M] /home/test/testmod/hello.o
In file included from <command-line>:0:
/home/test/android/kernel/include/linux/kconfig.h:4:32: error: generated/autoconf.h: No such file or directory
In file included from /home/test/android/kernel/arch/arm/include/asm/types.h:4,
from include/linux/types.h:4,
from include/linux/list.h:4,
from include/linux/module.h:9,
from /home/test/testmod/hello.c:1:
include/asm-generic/int-ll64.h:11:29: error: asm/bitsperlong.h: No such file or directory
In file included from /home/test/android/kernel/arch/arm/include/asm/posix_types.h:38,
from include/linux/posix_types.h:47,
from include/linux/types.h:17,
from include/linux/list.h:4,
from include/linux/module.h:9,
from /home/test/testmod/hello.c:1:
include/asm-generic/posix_types.h:70:5: warning: "__BITS_PER_LONG" is not defined
error, forbidden warning: posix_types.h:70
make[2]: *** [/home/test/testmod/hello.o] Error 1
make[1]: *** [_module_/home/test/testmod] Error 2
make[1]: Leaving directory `/home/test/android/kernel'
make: *** [default] Error 2
If I follow the suggestion in the output, and run 'make oldconfig && make prepare' on the kernel, it leads me through dozens of kernel config yes / no questions. After that, the compile still fails on the next error, which is about bitsperlong.h.
Android puts output binaries under out directory. So for example one can have out/target/product/<target name>/obj/KERNEL_OBJ/ or $ANDROID_PRODUCT_OUT/obj/KERNEL_OBJ/ if $ANDROID_PRODUCT_OUT is defined. This directory may have a different name from different vendors but simply that's the directory containing vmlinux.
So when you compile a kernel module under Android repo, you should submit make command like below inside your module's directory.
make -C $ANDROID_PRODUCT_OUT/obj/KERNEL_OBJ/ M=`pwd` ARCH=arm CROSS_COMPILE=arm-eabi- modules
Make modules should be done after compiling the kernel at least once. You have not compiled the kernel, that's why Module.symvers is missing. During compilation certain header files like asm/bitsperlong.h are created.
Firstly make sure that you have compiled kernel in the specified path.
that is
" /home/test/android/kernel" but you are using
" /home/android/kernel " during compilation of module
KERNELDIR ?= ~/android/kernel has to be KERNELDIR ?= ~/test/android/kernel
If not then in the ~/android/kernel directory run the below command to compile the kernel.
make ARCH=arm CROSS_COMPILE=~/test/android/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi
After your kernel is compiled you will get this "__BITS_PER_LONG" variable defined in System.map file of kernel i,e
~/test/android/kernel/System.map
After this you will be able to compile your module without any hurdle

Loading kernel module in Android kernel

I am listing my problem here.
I have a Google Nexus one a.k.a. "passion" phone with me. Fastboot and adb tools are installed in the phone. And the boot loader is unlocked.
My task: I have to add a linux kernel module to the Android kernel.
What I have done:
I followed the steps in http://source.android.com/source/initializing.html and downloaded the kernel for android-2.3.6_r1 (passion) and have built it. I am also able to flash it on the phone and the new android kernel also works fine. Now what I want is to modify the kernel and add my own kernel module and then flash it on the phone, so that the kernel on the phone is my modified kernel.
Now I have come across two approaches to do this.
1)
Cross Compile my kernel module with the android kernel and push it on the device with adb command. The Makefile I use in the kernel is as follows.
VERSION = 2
PATCHLEVEL = 3
SUBLEVEL = 6
EXTRAVERSION = -00054-g5f01537
obj-m += hello-1.o
KDIR=/home/apurva/android_dir
PWD := $(shell pwd)
all:
make -C $(KDIR) ARCH=arm CROSS_COMPILE=/home/apurva/android_dir/prebuilt/linux- x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- SUBDIRS=$(PWD) modules
clean:
make -C $(KDIR) ARCH=arm CROSS_COMPILE=/home/apurva/android_dir/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- SUBDIRS=$(PWD) clean
Now this is not able to generate new hello-1.ko. I do not know why, I guess there is some problem with the VERSION, PATCHLEVEL, SUBLEVEL and EXTRAVERSION values. Are these necessary? I tried these value from android-2.3.6_r1 also but still it does not work. I am not sure what is this EXTRAVERSION value?
I even tried with the hello-1.ko generated from the compiler in my ubuntu. I pushed this hello-1.ko into the emulator with the following adb command.
/root/bin/src/out/host/linux-x86/bin/adb shell mount
/root/bin/src/out/host/linux-x86/bin/adb push hello-1.ko /data
/root/bin/src/out/host/linux-x86/bin/adb insmod /data/hello-1.ko
But that hello-1.ko is not able to insmod and I get the following error.
insmod : Error in init_module() hello-1.ko function not implemented
Whereas the hello-1.c is quite simple:
#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");
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Goodbye world 1.\n");
}
2)
The second approach of doing this can be placing my source files of the kernel module in the kernel directory of android. May be in the system directory or somewhere else and ask the make to build these source files also along with the other source. But I am not sure where to ask the make process to do so. I tried to do so in main.mk and created a Android.mk file in the source directory of my source files but it did not work. May be this is a better solution but I could not find any help on this.
After doing this, my kernel modules should be able to control the wnic (Wireless Network Interface device) of the android phone. It should be able to put the wnic in sleep mode and then wake it up after receiving command from my kernel module. If you have some pointers on how to do this, that will be a help. I have found that on Android it is controlled through wpa_supplicant private driver. Commands, like:
wpa_cli driver powermode 0 - auto
wpa_cli driver powermode 1 - active
can do my task, but I am not sure since I have not tried. I have not reached that stage.
Please look into this and provide some help/guidance.
Thanks,
Apurva
Kernel modules (KO's) are much easier to work with than a static kernel - as long as the kernel has enabled them. The easiest way to tell is do an "adb shell lsmod". Second is to see if the kernel .config has enabled CONFIG_MODULES=y and CONFIG_MODULE_UNLOAD=y. Lots of info on the web about linux KO development.
Hummm, you're close but it looks like the makefile is screwy. First try to build the hello KO on your host for unit test, then build on your target. Here's a sample makefile I use on an OMAP36xx running gingerbread:
# Makefile for trivial android kernel module
obj-m += mod_hello.o
CROSS_COMPILE=/opt/distros/ARM/bin/arm-none-linux-gnueabi-
TARG_KDIR ?= /opt/android/dal/nook_kernel
HOST_KDIR=/lib/modules/$(shell uname -r)/build
# target creates:
# .<obj>.o: CC command line for the .o, including dependencies
# .<obj>.mod.o.cmd: CC command line for the mod.o, including dependencies
# .<obj>.ko.cmd: LD command line which links the .o and .mod.o to create the .ko
target:
#echo "Make module for target arm"
make -C $(TARG_KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) modules
host:
#echo "Make module for host"
make -C $(HOST_KDIR) M=$(PWD) modules
clean:
#echo "cleaning target"
make -C $(TARG_KDIR) M=$(PWD) clean
#echo "cleaning host"
make -C $(HOST_KDIR) M=$(PWD) clean
First check in the .config if the module support is enabled. (CONFIG_MODULES=y and CONFIG_MODULE_UNLOAD=y) if not enable them using menuconfig.
Then place your module on the root of the kernel source and add this to the main makefile you find at the root
core-y := usr/ yourModule/
and this to the yourModule folders makefile
obj-m := yourModule.o

Cross compile LKM module for Android platform

For work reasons, I need to develop a LKM for Android platform. I'm not very sure how to cross compile my AndroidModule.c and what tools to use for that. I guess that I'll need the source code of Android in order to tell the compiler to link the libraries from there right?
I will also need to download the ARM compiler for Android.
I think with those three things is enough (LKM Code in C, Android Source Code, ARM compiler for android).
The problem is that I can't find any tutorial that explains how to compile LKM for Android.
I'll be very pleased to have more info about it.
Here's a makefile that I use to build modules for Android.
I'm assuming you have a copy of the linux source somewhere and that you have built the kernel for your phone.
In your module directory I put a Makefile like this:
ifneq ($(KERNELRELEASE),)
obj-m := mymod.o
else
COMPILER ?=/pathtoandroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-
CROSS_COMPILE ?=$(COMPILER)
ARCH ?=arm
KERNELDIR ?= /home/kernel/androidkerneldir/
PWD := $(shell pwd)
EXTRACFLAGS += -I$(PWD)/somedirectory/shomewhere
default:
$(MAKE) -C $(KERNEL_DIR) M=`pwd` ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) EXTRA_CFLAGS=$(EXTRACFLAGS) modules
clean:
rm *.o *.ko
install:
adb push mymod.ko /system/lib/modules
This should do it for you. Make sure you have write permissions to /system directory.
Try the Android URL at the bottom it has detailed instructions on how to build the source.
Then follow this URL for final building (this is for dream release), I am assuming the procedure should hold good for other releases as well.
This should help.
To cross compile a module you'll need the kernel source code and the ARM compiler which is in the Android tool chain. You'll need a Makefile something along the lines of
obj-m:= AndroidModule.o
all: module
module:
$(MAKE) -C $(KERNELSRC) SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KERNELSRC) SUBDIRS=$(PWD) clean
#rm -f Module.symvers Module.markers modules.order
Then compile by configuring CROSS_COMPILE as the ARM compiler and KERNELSRC as the kernel source location, and calling make. Here's the command I use on 0xdriod.
CROSS_COMPILE=~/beagle-eclair/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- ARCH=arm KERNELSRC=~/kernel make

Categories

Resources