读书频道 > 系统 > linux > Linux内核精髓:精通Linux内核必会的75个绝技
编写特有的内核模块
2013-02-19 15:00:58     我来说两句 
收藏    我要投稿   
经过近20年的发展,Linux操作系统已经成为当今最成功的开源软件之一,使用广泛,影响深远。随着Linux操作系统功能的不断丰富和完善,Linux内核的源代码也从最初的几万行增加到如今的数百万行,庞大无比,对于Lin...  立即去当当网订购

下面将介绍如何编写内核源码树中所没有的特有内核模块。

以mymod模块为例说明,请将下面的代码以mymod.c为文件名保存。
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/errno.h>

static int sec = 5;
module_param(sec, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(sec, "Set the interval.");

static void mymod_timer(unsigned long data);

static DEFINE_TIMER(timer, mymod_timer, 0, 0);

static void mymod_timer(unsigned long data)
{
 printk(KERN_INFO "mymod: timer\n");
 mod_timer(&timer, jiffies + sec * HZ);
}

static int mymod_init(void)
{
 printk(KERN_INFO "mymod: init\n");

 if (sec <= 0) {
  printk(KERN_INFO "Invalid interval sec=%d\n", sec);
  return -EINVAL;
 }

 mod_timer(&timer, jiffies + sec * HZ);

 return 0;
}

static void mymod_exit(void)
{
 del_timer(&timer);
 printk(KERN_INFO "mymod: exit\n");
}

module_init(mymod_init);
module_exit(mymod_exit);

MODULE_AUTHOR("Hiroshi Shimamoto");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("My module");

在模块的源代码中包含(include)头文件linux/module.h。

名为module_int()和module_exit()的宏,可以调用回调(callback)函数来进行初始化和终止模块的处理。在模块的源文件中进行如下描述,就可以在添加模块时调用初始化函数,在删除模块时调用终止函数。

module_init(初始化函数名);

module_exit(终止函数名);

在这个例子模块的情形下调用的分别是mymod_init()和mymod_exit()。

初始化函数为了表示初始化已正常完成,需要返回0。按照Linux内核中的写法,发生错误(error)时将返回一个值为负数的错误代码。在这个例子中,如果设定值出错,则处理为-EINVAL(非法值)。

下面先用3个宏对模块进行定义,但在模块编写中并不是必需的。

MODULE_AUTHOR() 表示模块的作者

MODULE_LICENSE() 表示模块的许可证

MODULE_DESCRIPTION() 模块的说明

这个例子模块还用到了模块参数。模块参数可以使用module_param()宏来生成。

module_param(参数名,参数类型,权限(permission));

在例子模块中,sec定义为int类型的模块参数。

另外,还可以使用MODULE_PARM_DESC()宏来对模块参数进行说明。

先简单介绍一下这个例子的运行过程。当添加模块时,会调用指定为初始化函数的mymod_init()。在mymod_init()中首先通过printk()输出:

mymod: init

然后确认模块参数sec是否正常。在模块参数sec的值为0以下的异常情形时,会返回EINVAL错误代码并终止程序。在判断模块参数sec正常后,将内核计时器设置为sec秒后启动超时(timeout)函数mymod_timer()。在每隔sec秒启动的mymod_timer()中,首先使用printk()输出:

mymod: timer

再次设置sec秒的内核计时器,然后终止。当删除模块时,会调用mymod_exit()函数,删除内核计时器,通过printk()输出:

mymod: exit

于是模块终止。

接下来需要准备编写模块所需的Makefile。由于是使用内核的创建框架来生成,因此Makefile的内容非常简单。

obj-m :=mymod.o

最后执行下列make命令,通过当前目录(current directory)的源代码和Makefile生成模块mymod.ko。

# make -C /lib/modules/'uname 杛'/build M='pwd'

通过使用modinfo命令,可以看到所生成模块mymod.ko的信息。从这里可以看到使用MODULE_*宏所指定的内容。
# modinfo mymod.ko
filename:       mymod.ko
description:    My module
license:        GPL
author:         Hiroshi Shimamoto
srcversion:     61A3BB7CFC0C89B8344F5A5
depends:       
vermagic:       2.6.32-71.29.1.el6.x86_64 SMP mod_unload modversions
parm:           sec:Set the interval. (int)

点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:通过内核配置编写模块
下一篇:添加内核模块
相关文章
图文推荐
3.3.6 GNOME的软件管
3.3.5 GNOME的文件管
3.3.4 GNOME的窗口管
3.3.3 收藏夹和快捷
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做最好的IT技术学习网站