在 Android Emulator 裡面用 insmod 安裝 LKM 時,會報告錯誤,例如:
# insmod hello.ko
insmod: init_module 'hello.ko' failed (Function not implemented)
這是因為 Android SDK 裡面內建的 Emulator 所用的 kernel 關閉了載入 LKM 的功能。要在 Emulator 裡面開發和調試 LKM,必須自己重新編譯 kernel. 編譯方法可以參考 http://linuxclues.blogspot.com/2010/05/build-compile-linux-kernel-android.html.
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
從網上(例如:http://www.rockbox.org/tracker/9006?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><br />#include <linux/module.h><br />MODULE_LICENSE("Dual BSD/GPL");<br />static int hello_init(void)<br />{<br /> printk(KERN_INFO "Hello, world/n");<br /> return 0;<br />}<br />static void hello_exit(void)<br />{<br /> printk(KERN_INFO "Goodbye, cruel world/n");<br />}<br />module_init(hello_init);<br />module_exit(hello_exit);<br />
交叉編譯的 Makefile:
KERNELDIR := /Users/quaful/Documents/Projects/360/kernel/<br />PWD :=$(shell pwd)<br />ARCH=arm<br />CROSS_COMPILE=/Developer/android-ndk-r4b/build/prebuilt/darwin-x86/arm-eabi-4.4.0/bin/arm-eabi-<br />CC=$(CROSS_COMPILE)gcc<br />LD=$(CROSS_COMPILE)ld<br />obj-m := hello.o<br />modules:<br /> $(MAKE) -C $(KERNELDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules<br />clean:<br /> rm *.o *.ko *.mod.c *.markers *.order *.symvers<br />
把編譯產生的 hello.ko 傳到手機上,然後執行:
insmod hello.ko
在 kernel 的 console 輸出中就可以看到 printk 的結果了。