在 Android Emulator 里面用 insmod 安装 LKM 时,会报告错误,例如:
# insmod hello.ko
insmod: init_module 'hello.ko' failed (Function not implemented)
这是因为 Android SDK 里面自带的 Emulator 所用的 kernel 关闭了加载 LKM 的功能。要在 Emulator 里面开发和调试 LKM,必须自己重新编译 kernel. 编译方法可以参考 .
NOTE: 如果是在 Mac OS X 里面编译,make 的时候可能会遇到以下错误:
HOSTCC scripts/mod/mk_elfconfig
scripts/mod/mk_elfconfig.c:4:17: error: elf.h: No such file or directory
这是因为 Mac 的 include 文件少了一个 elf.h
从网上(例如:?getfile=16683)下载一个放到 scripts/mod 目录,并且修改 mod 目录里面引用了 elf.h 的两个文件就可以了。
编译好的新 kernel 假定是 zImage, 建议启动 emulator 的时候加上 -show-kernel 开关,这样可以把 LKM 用 printk() 输出的信息输出到 console 上,便于调试。例:emulator -kernel zImage -show-kernel -avd <AVD名字>
写一个简单的 Hello World 来测试一下:
#include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { printk(KERN_INFO "Hello, world\n"); return 0; } static void hello_exit(void) { printk(KERN_INFO "Goodbye, cruel world\n"); } module_init(hello_init); module_exit(hello_exit);
交叉编译的 Makefile:
KERNELDIR := /Users/quaful/Documents/Projects/360/kernel/ PWD :=$(shell pwd) ARCH=arm CROSS_COMPILE=/Developer/android-ndk-r4b/build/prebuilt/darwin-x86/arm-eabi-4.4.0/bin/arm-eabi- CC=$(CROSS_COMPILE)gcc LD=$(CROSS_COMPILE)ld obj-m := hello.o modules: $(MAKE) -C $(KERNELDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules clean: rm *.o *.ko *.mod.c *.markers *.order *.symvers
把编译生成的 hello.ko 传到手机上,然后执行:
insmod hello.ko
在 kernel 的 console 输出中就可以看到 printk 的结果了。