Linux 對大多數的驅動作了分類:塊設備驅動、網絡驅動、I 2 C 驅動、USB 驅動、SPI 驅動、音頻驅動等,而一些不好分類的則都歸納為 misc 類型設備驅動。
驅動模塊編譯步驟
1、準備源代碼
首先我們還是要編寫一個符合Linux格式的模塊文件,這樣我們才能開始我們的模塊編譯。例如:我們有一個源文件
mymodules.c
1. #include
2. #include
3. #include
4
5. MODULE_AUTHOR("Yu Qiang");
6. MODULE_LICENSE("GPL");
7
8. static int nbr = 10;
9. module_param(nbr, int, S_IRUGO);
10.
11. static int __init yuer_init(void)
12.{
13. ???int i;
14. ???for(i=0; i
15. ???{
16. ???????printk(KERN_ALERT "Hello, How are you. %d/n", i);
17. ???}
18. ???return 0;
19.}
20.
21.static void __exit yuer_exit(void)
22.{
23. ???printk(KERN_ALERT"I come from yuer's module, I have been unlad./n");
24.}
25.
26. module_init(yuer_init);
27. module_exit(yuer_exit);
yuer_init()函數將在模塊加載的時候運行,通過輸出的結果可以看到我們的模塊是否加載成功。
2、編寫Makefile文件
首先還是來看看我們Makefile的源文件,然后我們再來解釋;
Makefile
obj-m := modules.o???????????????????#要生成的模塊名
modules-objs:=?mymod.o????????#生成這個模塊名所需要的目標文件
KDIR := /lib/modules/`uname -r`/build
PWD := $(shell pwd)
default:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.o .* .cmd *.ko *.mod.c .tmp_versions
ARM平臺
Makefile
obj-m += mymod.o
KDIR := /home/workspace2/kernel/linux-2.6.25????#如果是用于arm平臺,則內核路徑為arm內核的路徑
PWD = $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.o
現在我來說明一下這個Makefile。請記住是大寫的Makefile而不是小寫的makefile;
obj-m :這個變量是指定你要聲稱哪些模塊,模塊的格式為 obj-m := <模塊名>.o
modules-objs :這個變量是說明聲稱模塊modules需要的目標文件 格式要求???<模塊名>-objs := <目標文件>
切記:模塊的名字不能取與目標文件相同的名字。如在這里模塊名不能取成 mymod;
KDIR???:這是我們正在運行的操作系統內核編譯目錄。也就是編譯模塊需要的環境
M=?????:指定我們源文件的位置
PWD???:這是當前工作路徑$(shell???)是make的一個內置函數。用來執行shell命令。
3、編譯模塊
現在我們已經準備好了我們所需要的源文件和相應的Makefile。我們現在就可以編譯了。在終端進入源文件目錄輸入make
運行結果:
make[1]: Entering directory `/usr/src/linux-headers-2.6.24-24-generic'
CC [M] /home/yuqiang/桌面/mymodule/mymodules.o
LD [M] /home/yuqiang/桌面/mymodule/modules.o
Building modules, stage 2.
MODPOST 1 modules
CC??????/home/yuqiang/桌面/mymodule/modules.mod.o
LD [M] /home/yuqiang/桌面/mymodule/modules.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.24-24-generic'
4、加載/卸載我們的模塊
從上面的編譯中我可以看到。已經有一個modules.ko生成了。這就是我們的模塊了。現在我們就可以來加載了。
首先在終端輸入:sudo insmod modules.ko
現在我們來看看我們的模塊加載成功沒有呢?
在終端輸入:dmesg | tail -12????這是查看內核輸出信息的意思。tail -12 顯示最后12條;
顯示結果如下:
[17945.024417] sd 9:0:0:0: Attached scsi generic sg2 type 0
[18046.790019] usb 5-8: USB disconnect, address 9
[19934.224812] Hello, How are you. 0
[19934.224817] Hello, How are you. 1
[19934.224818] Hello, How are you. 2
[19934.224820] Hello, How are you. 3
[19934.224821] Hello, How are you. 4
[19934.224822] Hello, How are you. 5
[19934.224824] Hello, How are you. 6
[19934.224825] Hello, How are you. 7
[19934.224826] Hello, How are you. 8
[19934.224828] Hello, How are you. 9
看到了吧。我們的模塊的初始化函數yuer_init();已經成功運行了。說明我們的模塊已經加載成功;
現在我們再來卸載模塊試試看。
在終端輸入:sudo rmmod modules
在終端輸入:dmesg | tail -3
[19934.224826] Hello, How are you. 8
[19934.224828] Hello, How are you. 9
[20412.046932] I come from yuer's module, I have been unlad.
可以從打印的信息中看到,我們的模塊的退出函數已經被執行了。說明我們的模塊已經被成功的卸載了。到目前位置我們就已經算是對模塊的編譯到編譯運行算是有了一個整體上的認識了。對于以后深入的學習還是應該有點幫助的。