2012年2月20日 星期一

編譯簡單的Kernel modules

轉自於 http://telesky.pixnet.net/blog/post/6969608-cross-compile-the-linux-device-driver-example%3A-hello-module

1. mkdir hello_module   建立一個資料夾來開發
2. 在 /hello_module 內建立 hello.c 與 Makefile
    hello.c :
                       #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 := /home/xxx/android/kernel/             
                      PWD :=$(shell pwd)
                      ARCH=arm                    
                      CROSS_COMPILE=/home/xxx/android/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/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
                      #============================================================
                      KERNELDIR: 指名你的kernel source, 通常會在 /usr/src/ 裡面找到,
                                          輸入uname –r 也可以看到你目前的 kernel 版本
                     -C 後面代表你的kernel source 目錄所在地
                      M= 後面代表你的 module(hello.c) 目錄所在地,
                           $(shell pwd) 就是目前所在目錄
                      $(MAKE) 跟  rm 的前面似乎不能用空白鍵, 改用<TAB>吧!

3. Prepare your kernel
     我就是這一關卡很久, 如果你的kernel沒有先設置好的話,
     會有一堆問題而且很難根據 Error Message 去 debug
     首先, 進入到你的 kernel source 目錄下 (我的是 /home/xxx/android/kernel )
     # vim Makefile
     找到 ARCH 跟CROSS_COMPILE 的位置
     把原本的
                  ARCH                    ?= $(SUBARCH)
                  CROSS_COMPILE  ?=
     改成
                  ARCH           := arm
                  CROSS_COMPILE  := /home/xxx/android/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-
     然後輸入 make mrproper 先清掉一些垃圾
     輸入 make oldconfig , 會出現一堆東西給你選, 都按 Enter 應付它就對了
     輸入 make modules_prepare , 這一步是關鍵, 如果沒有 Error,
     就可以到 step 4 準備領回你的 hello.ko 囉!
4. make your module
    進入 /hello_module , 輸入 make
    若沒有Error , 應該會看到以下畫面, 也會看到一堆東西生出來了, 當然也有最重要的 hello.ko !!
    make -C /home/xxx/android/kernel/ ARCH=arm CROSS_COMPILE=/home/xxx/android/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi- M=/home/xxx/android/hello_module modules
    make[1]: Entering directory `/home/xxx/android/kernel'

          WARNING: Symbol version dump /home/xxx/android/kernel/Module.symvers
           is missing; modules will have no dependencies and modversions.

    CC [M]  /home/xxx/android/hello_module/hello.o
    Building modules, stage 2.
    MODPOST 1 modules
    CC      /home/xxx/android/hello_module/hello.mod.o
    LD [M]  /home/xxx/android/hello_module/hello.ko
    make[1]: Leaving directory `/home/xxx/android/kernel'
5. insmod/rmmod (掛載/卸載)
    insmod hello.ko 或 rmmod hello.ko   來看你編寫的 driver 給你什麼訊息
    通常按下去什麼都沒看到, 要到/var/log/messages 或輸入 dmesg 去看

     May 11 10:32:49 localhost kernel: Hello, world
     May 11 10:37:25 localhost kernel: Goodbye, cruel world
     (ps: 不過因為我操作的工作站環境的 kernel 不是 android 的,
            且預設架構是 x86 不是 ARM,
            所以在工作站上會出現
            insmod: error inserting 'hello.ko': -1 Invalid module format 的訊息
            把 hello.ko 放到我的 android 環境中的 /sdcard 後 ,
            輸入 insmod/rmmod 就可以看到訊息囉!
            # insmod hello.ko
               Hello, world
            # rmmod hello.ko
               Goodbye, cruel world
             )

沒有留言:

張貼留言