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!

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