linux设备驱动编程-初探(2)--在内核中构造和运行模块

【参考资料】:

1:O'REILLY 写的《LINUX 设备驱动程序》第三版

2:http://hi.baidu.com/freshwater2009/blog/item/9dc7a0c0b4ed27100ff47730.html 

3:http://blog.csdn.net/sunnyclub/archive/2009/07/24/4377305.aspx

在真正进入编写linux下的设备驱动程序之前,我觉得有必要把相关的基础知识看仔细,理解清楚,然后还需要将所涉及到的相关环境,代码版本也需要一一搞清楚,这样才能准备好,养成良好的习惯,以致以后在实际的开发中,不要因为之前准备工作的不足,发生意想不到的错误。废话不多说,直接上实用的。。。。

【成为2.6.x内核构造模块的条件】

1:从kernel.org网站下载一个”主线“内核,安装到自己的系统中【目前内核最新版本2.6.34】;

2:还必须要在自己的内核中构造好自己的内核源代码树;

这里我的理解是:首先为什么要成为内核的模块,因为之后我们对于设备的驱动程序都是以模块话注册到内核中去的,作为一个内核的模块,在操作系统的控制下,供应用程序及相关的代码进行调用,保证了驱动程序的正确发挥其作用。为什么要模块话?这个问题我想可以这么说,驱动程序模块化之后,可以将驱动程序部分的内容像一个部件一样,可以自由的安装(注册)拆卸(卸载),保证对内核的其他模块的干扰,也方便驱动开发人员与内核的其他开发人员依赖性降低。对于以上的第1点,下载一个主线内核,指的是从kernel.org网站中下载的标准内核源码,我下载的版本是2.6.34,至于说安装到自己的系统中,我用的是ubuntu8.10,内核版本是:2.6.27-16-generic.如何安装”主线“内核到自己的系统中,可以参考以下网址:

http://hi.baidu.com/freshwater2009/blog/item/9dc7a0c0b4ed27100ff47730.html 

http://blog.csdn.net/sunnyclub/archive/2009/07/24/4377305.aspx

中写的文章,安装完成之后,基本的linux设备驱动程序所需要的内核源代码树也就建成了。

尝试运行内核模块】

使用一个示例来运行任何模块化驱动程序,在linux下编写的驱动一般都是以模块化在内核中运行。在之前已经设定好示例相关的环境,接下去按照书上一个示例来进行理解:

#include
#include

MODULE_LICENSE(“Dual BSD/GPL”) /* special MARCO, register free license */

static int hello_init(void)      { printk(KERN_ALERT "<1>Hello, world/n"); return 0; }  /* use the function when the module  is registed to the kernel */
static void hello_exit(void)  { printk(KERN_ALERT "<1>Goodbye cruel world/n"); }  /* use the function when the module  is exit from the kernel */

module_init(hello_init); /* 针对这2个特殊的宏,再另外一篇中总结一下 */

module_exit(hello_exit);

其中【KERN_ALERT】是一个定义优先级的字符串,这里书上指明这里这样写的原因是由于默认的优先级可能让消息不会输出到控制台上,所以这里需要提高优先级,使示例程序的消息输出能够显示出来。

另外执行这个测试程序需要一个makefile文件:

obj-m := hello_printk.o

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

PWD   := $(shell pwd)

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

这个makefile文件经过我的调查和理解如以下内容:

▲obj-m指出将要编译成的内核模块列表。.o格式文件会自动地有相应的.c文件生成(不需要显示的罗列所有源代码文件)

▲KDIR表示是内核源代码的位置。在当前标准情况是链接到包含着正在使用内核对应源代码的目录树位置。

▲PWD指示了当前工作目录并且是我们自己内核模块的源代码位置

▲default是默认的编译连接目标;即,make将默认执行本条规则编译目标,除非程序员显示的指明编译其他目标。这里的的编译规则的意思是,在包含内核源代码位置的地方进行make,然后之编译$(PWD)(当前)目录下的modules。这里允许我们使用所有定义在内核源代码树下的所有规则来编译我们的内核模块。

编译及运行代码的过程:

1:转到储存该代码的目录,执行命令 cd hello_printk

2:执行命令: make 这样在该目录下会多出几个文件 Module.symvers, hello_printk.ko, hello_printk.mod.c, hello_printk.mod.o, hello_printk.o, modules.order;

3:装载该内核模块,执行命令: sudo insmod ./hello_printk.ko 然后使用命令dmesg,在屏幕中可以看到 Hello world!出现了。

4:卸载该内核模块的命令: rmmod hello_printf 然后再使用命令dmesg,在屏幕中可以看到 Goodbye, world!出现了。

以上就是在linux内核中如何加载一个模块和卸载一个模块的方法。设备驱动程序也是通过这样使之成为一个模块,然后向内核进行加载和卸载的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值