简体   繁体   中英

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM