Linux設備驅動開發之hello, world

Linux內核編譯 一文中介紹了Linux 2.6內核的編譯與安裝工作,今天介紹一下Linux設備驅動開發的hello, world程序。

進行Linux設備驅動開發必須準備好Linux內核編譯環境,設備驅動程序依賴於這個環境。

下面是一個完整的hello, world驅動程序。

#include <linux/init.h>
#include <linux/module.h>

static int __init
hello_init(void)
{
	printk("Hello, world!\n");
	return 0;
}


module_init(hello_init);


static void __exit
hello_exit(void)
{
	printk("Goodbye, world!\n");
}

module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Valerie Henson <[email protected]>");
MODULE_DESCRIPTION("\"Hello, world!\" minimal module");
MODULE_VERSION("printk");
首先初始化函數和退出函數都聲明爲static類型,這是因爲這兩個函數不會被外部其它代碼調用。__init關鍵字告訴內核這是一個設備驅動程序的初始化函數,內核會並且只會調用一次該函數來進行驅動程序的初始化工作。同理,__exit關鍵字告訴內核這是一個設備驅動程序的退出函數,內核會並且只會調用一次該函數進行驅動程序的退出工作。

module_init(hello_init)用於設置設備驅動程序的初始化函數,module_exit(hello_exit)用於設置驅動程序的退出函數。

MODULE_LICENSE設置程序許可協議。如果不設置許可協議,內核會發出警告信息,設置內核某些功能不能被使用。

MODULE_AUTHOR設置程序作者。

MODULE_DESCRIPTION設置程序描述信息。

MODULE_VERSION設置程序版本。


程序的makefile如下:

obj-m := hello_printk.o 

KDIR  := /lib/modules/$(shell uname -r)/build

PWD   := $(shell pwd)

default:
	$(MAKE) -C $(KDIR) M=$(PWD) modules

obj-m指明需要編譯成的驅動程序,o文件由相應的c文件編譯得到。如果需要多個文件可以使用module-objs來列出多文件。

KDIR是內核驅動模塊位置。

PWD是當前目錄。

default是makefile默認目標。


進入makefile所在目錄,運行make並將hello, world加載到內核。

yongmi@yongmi-hn:~/ldd/hello_printk$ make
make -C /lib/modules/2.6.32-5-686/build M=/home/yongmi/ldd/hello_printk modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-5-686'
  Building modules, stage 2.
  MODPOST 1 modules
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-5-686'
yongmi@yongmi-hn:~/ldd/hello_printk$ su
Password: 
root@yongmi-hn:/home/yongmi/ldd/hello_printk# insmod hello_printk.ko 
root@yongmi-hn:/home/yongmi/ldd/hello_printk# dmesg | tail
[234781.145121] rtw_set_ps_mode(): Busy Traffic , Leave 802.11 power save..
[234781.145446] rtl8192c_set_FwPwrMode_cmd(): Mode = 0, SmartPS = 0
[234782.518827] survey done event(19)
[234783.704198] rtw_set_ps_mode(): Enter 802.11 power save mode...
[234783.704205] rtl8192c_set_FwPwrMode_cmd(): Mode = 1, SmartPS = 2
[234791.704197] rtw_set_ps_mode(): Busy Traffic , Leave 802.11 power save..
[234791.704316] rtl8192c_set_FwPwrMode_cmd(): Mode = 0, SmartPS = 0
[234793.704205] rtw_set_ps_mode(): Enter 802.11 power save mode...
[234793.704214] rtl8192c_set_FwPwrMode_cmd(): Mode = 1, SmartPS = 2
[234793.851115] Hello, world!
root@yongmi-hn:/home/yongmi/ldd/hello_printk# 

可以看到驅動程序初始化函數被調用,在日誌文件中有hello, world字符串。


現在將hello, world驅動卸載下來:

root@yongmi-hn:/home/yongmi/ldd/hello_printk# rmmod hello_printk
root@yongmi-hn:/home/yongmi/ldd/hello_printk# dmesg | tail
[234975.704231] rtl8192c_set_FwPwrMode_cmd(): Mode = 1, SmartPS = 2
[234977.704225] rtw_set_ps_mode(): Busy Traffic , Leave 802.11 power save..
[234977.704340] rtl8192c_set_FwPwrMode_cmd(): Mode = 0, SmartPS = 0
[234979.704223] rtw_set_ps_mode(): Enter 802.11 power save mode...
[234979.704230] rtl8192c_set_FwPwrMode_cmd(): Mode = 1, SmartPS = 2
[234989.704231] rtw_set_ps_mode(): Busy Traffic , Leave 802.11 power save..
[234989.704331] rtl8192c_set_FwPwrMode_cmd(): Mode = 0, SmartPS = 0
[234991.704226] rtw_set_ps_mode(): Enter 802.11 power save mode...
[234991.704234] rtl8192c_set_FwPwrMode_cmd(): Mode = 1, SmartPS = 2
[234993.696774] Goodbye, world!
root@yongmi-hn:/home/yongmi/ldd/hello_printk#

內核調用了退出函數,並打印了Goodbye, world字符串。


本文簡要介紹了Linux設備驅動開發信息,程序中用到的代碼可以在這裏下載。



參考資料:

《Linux設備驅動開發》

Linux設備驅動Hello World程序介紹

hello,Kernel!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章