慢慢学Linxu驱动开发,第二篇:启程,模块机制,Hello World

1.启程   

 
      重头开始看《Linux的那些事儿——我是U盘》,首先是下了书中用的Linux2.6.10内核版本,以前看这书都是用Linux2.6.33.7的版本,不过细细一看发现两者的差距还是蛮大的,统一一下版本对以后的学习应该备有好处的,必须的。

 

      既然是专门学习U盘的驱动,那么非U盘驱动一概忽略也是必须的,通过Kconfig可以得知只有config USB_STORAGE才是需要看的,不免压力很小,代码量瞬间减少很多。

    //Kconfig  
config USB_STORAGE
tristate "USB Mass Storage support"
depends on USB
select SCSI

注:
 还有一个debug的部分

    //Kconfig  
config USB_STORAGE_DEBUG
bool "USB Mass Storage verbose debug"
depends on USB_STORAGE

      这个编译选项不是必须的,但是如果真的要自己修改或者调试usb-storage的代码,那么打开这个选项是很有必要的,因为它会负责打印一些调试信息。

 

再翻到Makefile文件看到(文件最后)相对应要看的C文件有

 

    //Makefile  
usb-storage-objs := scsiglue.o protocol.o transport.o usb.o /
initializers.o $(usb-storage-obj-y)

以及它们同名的.h头文件,当然内核驱动模块间也是有联系的,简单的看完这几个文件显然是不够的,这些暂且按下不表。

 


这个表示压力不大。

 

2.模块机制与Hello World

 

      因为模块机制的存在,意味着可以把庞大的Linux内核划分为许许多多个小的模块,对于编写设备驱动程序的人来说,不再需要平凡的reboot,只要加载(insmod),卸载(rmmod)就可以了,舒服多了。

 

 内核的Hello World也没啥难的。

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

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("fudan_abc");

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

static void __exit hello_exit(void)
{
printk("<0>""Goodbye, cruel world/n");
}

//两个必须的宏,对于动态模式编写来说
module_init(hello_init); //使用insmod去安装模块时,module_init()注册的函数将被执行
module_exit(hello_exit); //使用rmmod去卸载模块时,module_exit()注册的函数将被执行


这里要讲讲printk()函数,必须的,但另外开一篇讲,这里先继续按下不表。

 

配合的Makefile

    ifeq ($(KERNELRELEASE),)  
KERNELDIR ?= /lib/modules/$(shell uname -r)/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 .temp_versions

.PHONY:modules modules_install clean

else
obj-m := hello.o
endif

这里在make之前,要先建立内核源码树,方法去百度把。

比如:http://wenku.baidu.com/view/25c5ec65f5335a8102d220eb.html

在当前目录下make,会生成一个hello.ko文件,这就是要测试的模块。

 

执行命令,insmod hello.ko
输入dmesg看到Hello,World!被打印出来。
再输入rmmod hello.ko
可以看到Goodbye,cruel world被打印出来。

注:

书上说的看日志的方法至少我这里看不到,情况不明,弄明白了我再说,至于这个dmesg命令,Linux命令dmesg用来显示开机信息,kernel会将开机信息存储在ring buffer中。您若是开机时来不及查看信息,可利用dmesg来查看。   

 

也就是Linux内核模块,貌似还是很简单的,记住每个动态加载模块都是从module_init开始,以module_exit结束的。

 

------------------------------------------------------------------------------------------------------------------

 

作者:庞辉

 

出处:http://www.cnblogs.com/pang123hui/

 

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名庞辉(包含链接).


posted @ 2011-04-01 00:06  云说风轻  阅读(554)  评论(0编辑  收藏  举报