以LDD3上的hello.c爲例:
//hello.c #include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { printk(KERN_ALERT "Hello, world\n"); return 0; } static void hello_exit(void) { printk(KERN_ALERT"Goodbye, cruel world\n"); } module_init(hello_init); module_exit(hello_exit); |
Makefile文件的內容爲:
obj-m := hello.o KERNELDIR := /lib/modules/2.6.20/build PWD := $(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules modules_install: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions |
其中,hello.c和Makefile文件應該位於同一個目錄下,可以放在/home下,我的兩個文件都位於/home/david/.
第四步:編譯和裝載模塊
在文件所處的目錄下,執行:
debian:/home/david # make
然後查看該目錄下有哪些文件生成:
debian:/home/david # ls -l 總計 28 drwxr-xr-x 2 david david 4096 2007-02-07 17:49 Desktop -rw-r--r-- 1 david david 462 2007-07-20 13:42 hello.c -rw-r--r-- 1 root root 2432 2007-07-20 13:55 hello.ko -rw-r--r-- 1 root root 607 2007-07-20 13:55 hello.mod.c -rw-r--r-- 1 root root 1968 2007-07-20 13:55 hello.mod.o -rw-r--r-- 1 root root 1140 2007-07-20 13:55 hello.o -rw-r--r-- 1 david david 267 2007-07-20 13:48 Makefile -rw-r--r-- 1 root root 0 2007-07-05 14:11 Module.symvers |
回顧文章:Linux常用基本命令及應用技巧
新手剛剛接觸linux的時候可能處處感到不便,不過沒有關係,接觸新的事物都有這樣的一個過程,在你用過Linux一段時間後,你就會逐漸瞭解Linux其實和Windows一樣容易掌握。由於操作和使用環境的陌生,如果要完全熟悉Linux的應用我們首先要解決的問題就是對Linux常用命令的熟練掌握。
可見,已經生成模塊文件hello.ko.
然後,就可以加載該模塊:
debian:/home/david # insmod hello.ko
查看模塊是否加載進內核:
debian:/home/david # lsmod
Module Size Used by
hello 1344 0
nfs 219468 0
nfsd 202224 17
…… ……
其中Module名爲hello的即爲我們所加載的模塊.
卸載模塊:
debian:/home/david # rmmod hello
同樣可以通過lsmod來查看該模塊是否被卸載.
這裏有兩個問題,其一就是printk()輸出的問題.LDD3上也說,在加載和卸載模塊的時候都會有信息輸出在屏幕上,如果在Windows下通過終端仿真器(我們常用的虛擬機算是一種),則在屏幕上看不到任何輸出.我同時在虛擬機和和物理機都運行了該模塊,均未看到有"Hello, world"(加載模塊時printk的輸出)或"Goodby, cruel world"(卸載模塊時printk的輸出). 這個不知道是我操作系統發行版的原因還是系統配置的問題,請了解這個問題的朋友指點一下.
其二,書上講到如果屏幕上看不到信息,可能輸出在某個日誌文件裏面了,並說可能在/var/log/messages文件中.並且看到網上很多網友也說是輸出到這個文件裏面.我不知道有沒有發現輸出在其他日誌文件裏的,不過我的這個信息輸出在/var/log/syslog裏面.在加載和卸載完該模塊後, 執行命令:
debian:/home/david # cat /var/log/syslog | grep world
可以看到有兩行內容.當然,也可以不用grep world, 應該會出現在最後兩行.
Jul 20 14:15:29 localhost kernel: Hello, world
Jul 20 14:15:34 localhost kernel: Goodbye, cruel world
這就是printk應該輸出的信息.
這裏有另外一個方法,可以實現printk的信息輸出在屏幕上,即更改printk輸出的優先級.例子中的優先級爲:KERN_ALERT,優先級爲<1>,如果將優先級改爲KERN_EMERG即<0>,則可以看到屏幕的輸出信息.
修改的方法只是修改一下hello.c中兩句printk()的內容,修改後的hello.c如下:
#include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { printk(KERN_EMERG "Hello, world\n"); /*改動部分*/ return 0; } static void hello_exit(void) { printk(KERN_EMERG"Goodbye, cruel world\n"); /*改動部分*/ } module_init(hello_init); module_exit(hello_exit); |
debian:/home/david# insmod hello.ko debian:/home/david# Message from syslogd@localhost at Fri Jul 20 14:27:32 2007 ... localhost kernel: Hello, world debian:/home/david# rmmod hello debian:/home/david# Message from syslogd@localhost at Fri Jul 20 14:27:42 2007 ... localhost kernel: Goodbye, cruel world debian:/home/david |
以上就是整個2.6內核編譯步驟以及模塊動態加載的方法.理解和解釋有誤的地方,也請各位瀏覽本文的朋友指點,也希望能和對內核和驅動感興趣的朋友交流。
回顧文章:Linux常用基本命令及應用技巧
新手剛剛接觸linux的時候可能處處感到不便,不過沒有關係,接觸新的事物都有這樣的一個過程,在你用過Linux一段時間後,你就會逐漸瞭解Linux其實和Windows一樣容易掌握。由於操作和使用環境的陌生,如果要完全熟悉Linux的應用我們首先要解決的問題就是對Linux常用命令的熟練掌握。