1. 將 .config 從模擬器裡抓出來
因為模擬器裡的 kernel 的 CONFIG_MODULE 是關掉的。所以我們需要將它打開,否則不能 insmod 。
開了之後就要重 build 出 kernel image (zImage). 而要 build kernel 就需要模擬器裡的 kernel 的 .config。
先下載 Android 的 sdk , 因為 emulator 就在 SDK 裡,可到下面網址 download(註:我是以SDK 1.1為例子,SDK 1.5 還沒試過)
http://developer.android.com/sdk/1.1_r1/index.html |
a. 解壓之後,執行 emulator
D:\workplace\android-sdk-windows-1.1_r1\tools>emulator |
b. 在 emulator 執行的狀況下抓/proc/config.gz ,放到 \pulldata下
D:\workplace\android-sdk-windows-1.1_r1\tools>adb pull /proc/config.gz |
2. 改 CONFIG_MODULES
將 config.gz 解壓之後放到 /mydroid/kernel 下, 然後找 CONFIG_MODULES ,並改為
CONFIG_MODULES=y |
3. 改 kernel 的 Makefile
因為我們是跑 arm archtecture ,所以要改 tool chain
在 /mydroid/kernel/Makefile 裡,將 ARCH 跟 CROSS_COMPILE 改為下面
ARCH ?=arm CROSS_COMPILE ?=../prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi- |
然後將 LDFLAGS_BUILD_ID mark 掉,如下
# LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,$(call ld-option, -Wl$(comma)--build-id,)) |
4. build kernel
(1) 先清乾淨
$make mrproper |
(2) 將第二步驟的 config 改名為 .config ,放到 /mydroid/kernel 下
(3) make
$make |
一開始會問你一些問題,一律都答N
build 完之後,會在 /mydroid/kernel/arch/arm/boot 找到 image, 叫 zImage
5. build fake driver
(1) 從 Linux Device Driver Programming 一書裡,copy 個範例 driver, source C 如下
/* * devone.c * */ #include linux/init.h #include linux/module.h #include linux/types.h #include linux/kernel.h #include linux/fs.h #include linux/cdev.h #include asm/uaccess.h MODULE_LICENSE("Dual BSD/GPL"); static int devone_devs = 1; /* device count */ static int devone_major = 0; /* dynamic allocation */ static int devone_minor = 0; static struct cdev devone_cdev; ssize_t devone_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { int i; unsigned char val = 0xff; int retval; for (i = 0 ; i < count ; i++) { if (copy_to_user(&buf[i], &val, 1)) { retval = -EFAULT; goto out; } } retval = count; out: return (retval); } struct file_operations devone_fops = { .read = devone_read, }; static int devone_init(void) { dev_t dev = MKDEV(devone_major, 0); int alloc_ret = 0; int major; int cdev_err = 0; alloc_ret = alloc_chrdev_region(&dev, 0, devone_devs, "devone"); if (alloc_ret) goto error; devone_major = major = MAJOR(dev); cdev_init(&devone_cdev, &devone_fops); devone_cdev.owner = THIS_MODULE; devone_cdev.ops = &devone_fops; cdev_err = cdev_add(&devone_cdev, MKDEV(devone_major, devone_minor), 1); if (cdev_err) goto error; printk(KERN_ALERT "devone driver(major %d) installed.\n", major); return 0; error: if (cdev_err == 0) cdev_del(&devone_cdev); if (alloc_ret == 0) unregister_chrdev_region(dev, devone_devs); return -1; } static void devone_exit(void) { dev_t dev = MKDEV(devone_major, 0); cdev_del(&devone_cdev); unregister_chrdev_region(dev, devone_devs); printk(KERN_ALERT "devone driver removed.\n"); } module_init(devone_init); module_exit(devone_exit); |
Makefile 如下,你需要改 KERNELDIR ,這需要指到已經好的kernel,還有命令之前一定要是"tab"
KERNELDIR=/home/arik/Workspace/aydroid/kernel/ PWD := $(shell pwd) obj-m := devone.o modules: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: rm -rf *.o *~ core.depend .*.cmd *.ko *.mod.c .tmp_versions |
6. 將我們 build 的 zImage 放進 emulator 上跑
D:\workplace\android-sdk-windows-1.1_r1\tools>emulator.exe -kernel D:\workplace\ android-sdk-windows-1.1_r1\tools\lib\images\zImage |
-kernel 後面的參數就是指到之前 build 出來的 kernel image
7. 把 busybox 放進 emulator
因為待會要用 busybox 的 mknod 指令( emulator 好像沒有), 所以要將 busybox 放進 emulator
(1) 讓 emulator 的 /system 這個目錄變成可 read/write. 開另一個 cmd 下
D:\workplace\android-sdk-windows-1.1_r1\tools>adb remount * daemon not running. starting it now * * daemon started successfully * remount succeeded |
(2) 下載 busybox
http://benno.id.au/android/busybox |
(3) 把 busybox 放進 emulator
D:\workplace\android-sdk-windows-1.1_r1\tools>adb push busybox /system/bin 1703 KB/s (0 bytes in 1745016.001s) |
(4) 更改 busybox 權限,否則不能用
D:\workplace\android-sdk-windows-1.1_r1\tools>adb shell # chmod 566 /system/bin/busybox chmod 566 /system/bin/busybox #_ |
8. 把 ko 檔放進 emulator
跟放 busybox 一樣, 把假 driver 放進, 注意 emulator 裡只有 /system 目錄才可對外讀寫, 這裡我是放在 /system/bin
D:\workplace\android-sdk-windows-1.1_r1\tools>adb push devone.ko /system/bin 117 KB/s (0 bytes in 3763.000s) |
9. 載入 module
跟在 linux 下做的一樣
D:\workplace\android-sdk-windows-1.1_r1\tools>adb shell # busybox insmod /system/bin/devone.ko busybox insmod /system/bin/devone.ko # busybox lsmod busybox lsmod Module Size Used by Not tainted devone 2624 0 # |
10. 將 driver 掛上
掛上之前,要先知道它的 major id
# busybox cat /proc/devices busybox cat /proc/devices Character devices: 1 mem 4 /dev/vc/0 4 tty 5 /dev/tty 5 /dev/console 5 /dev/ptmx 7 vcs 10 misc 13 input 29 fb 90 mtd 128 ptm 136 pts 252 devone 253 ttyS 254 rtc Block devices: 1 ramdisk 7 loop 31 mtdblock 43 nbd 179 mmc # |
知道是 252 之後,就 mknod 上去
# busybox mknod /dev/devone c 252 0 busybox mknod /dev/devone c 252 0 # busybox ls -l /dev/devone busybox ls -l /dev/devone crw-rw-rw- 1 0 0 252, 0 Apr 30 02:26 [1;35m/dev/devone[0m # |
3 comments:
請問一下大大
我照著你的步驟下去測試,前面都沒有問題
可是到了要掛載模組時,出現了錯誤
# busybox insmod /system/bin/devone.ko
insmod: cannot insert '/system/bin/devone.ko': invalid module format (-1): Exec format error
一直找不到解決的方法 請問大大知不知道這大概是什麼原因造成的呢?
謝謝^^
應該是compiler 版本的問題,
我之前也有遇到一樣的問題 ~
改了 Makefile 的 gcc 就解決了.
大大請問一下
我在/mydroid/kernel 這個路徑上迷惑了,請問這個路徑是哪裡的??是從Andriod官網上下載下來的source code嗎?我現在下載的2.1版,裡面沒有kernel這個目錄,還是是我弄錯了。
此外,有另一個問題想請教,我們目前把Andriod安裝在一個netbook上,我們想把之前的linux driver安裝在這上面,我們driver在build的時候, KERNELDIR這個路徑應該指到source code的哪裡呢?
謝謝~~
Post a Comment