2011年12月30日 星期五

基礎 Linux Device Driver 驅動程式#3 (hello_multifile驅動)

hello_multifile這支驅動程式與hello驅動程式其實沒太多的差別,
只是差在此驅動程式會引用到其他模組的函式如此。

以下是main.c 的程式碼:
/*****************************************************************************/
   
     1 #include <linux/module.h>
     2 #include <linux/init.h>
     
     3 extern void sub();
     
     4 static int hello_multifile_init(void)
     5 {
     6 printk(KERN_ALERT "hello_multifile is loaded.\n");
     7 sub();
     8 return 0;
     9 }
     
     
    10 static int hello_multifile_exit(void)
    11 {
    12 printk(KERN_ALERT "hello_multifile is unloaded.\n");
    13 }
     
    14 module_init(hello_multifile_init);
    15 module_exit(hello_multifile_exit);
     
    16 MODULE_LICENSE("GPL");
    17 MODULE_AUTHOR("Wang Chen Shu");
    18 MODULE_DESCRIPTION("Sample test.");

/*****************************************************************************/
看到這一行了嗎?
3  extern void sub();
學過C語言的都知道,
這一行是告訴編譯器說 sub() 在其它位置被定義了,
編譯器就會試著去找sub。


以下是sub.c 的程式碼:
/*****************************************************************************/

     1 #include <linux/module.h>
     2 #include <linux/init.h>
     
     3 void sub(void)
     4 {
     5 printk(KERN_ALERT "%s: sub() called\n", __func__);
     6 }

/*****************************************************************************/

Makefile如下:

/*****************************************************************************/

     1 CFILES := main.c sub.c
     2 obj-m := hello.o
     3 hello-objs := $(CFILES:.c=.o)
     
     4 KDIR="/opt/linux-source-2.6.38/"
     5 PWD=$(shell pwd)
     
     6 all:
     7 $(MAKE) -C $(KDIR) M=$(PWD) modules
     8 clean:
     9 $(MAKE) -C $(KDIR) M=$(PWD) clean
    10

/*****************************************************************************/

話不多說,就直接來給它編譯下去囉^^

# make
make -C "/opt/linux-source-2.6.38/" M=/opt/test_driver/my_driver/hello_multifile modules
make[1]: Entering directory `/opt/linux-source-2.6.38'
  CC [M]  /opt/test_driver/my_driver/hello_multifile/main.o
/opt/test_driver/my_driver/hello_multifile/main.c:4:1: warning: function declaration isn’t a prototype
/opt/test_driver/my_driver/hello_multifile/main.c: In function ‘hello_multifile_exit’:
/opt/test_driver/my_driver/hello_multifile/main.c:17:1: warning: no return statement in function returning non-void
/opt/test_driver/my_driver/hello_multifile/main.c: In function ‘__exittest’:
/opt/test_driver/my_driver/hello_multifile/main.c:20:1: warning: return from incompatible pointer type
  CC [M]  /opt/test_driver/my_driver/hello_multifile/sub.o
  LD [M]  /opt/test_driver/my_driver/hello_multifile/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /opt/test_driver/my_driver/hello_multifile/hello.mod.o
  LD [M]  /opt/test_driver/my_driver/hello_multifile/hello.ko
make[1]: Leaving directory `/opt/linux-source-2.6.38'

此時目錄就會多出hello.ko, 如下:

# ls
hello.ko  hello.mod.c  hello.mod.o  hello.o  main.c  main.o  Makefile  modules.order  Module.symvers  README  sub.c  sub.o

有了模組,接下來當然是載入囉,還用得著多說嗎?
# insmod hello.ko
hello_multifile is loaded.
sub: sub() called
看到了嗎? 它引用了sub。
移除模組也是和hello一樣的做法。
# rmmod hello
hello_multifile is unloaded.
這樣就成功的移除了模組。


註記及聲明:
本教學,是參考Linux Device Driver Programming驅動程式設計由平田豐著的這本書。


沒有留言:

張貼留言