Linux内核模块作用及组成

前言:现代操作系统的一个发展方向是采用微内核,与传统的单一内核相比,不仅简单易于实现,而且特别灵活,Linux内核虽然没有采用微内核,但是它却采用了微内核的思想,设计了可装载的模块。

一、模块的作用

Linux的内核模块机制允许开发者动态的向内核添加功能,我们常见的文件系统、驱动程序等都可以通过模块的方式添加到内核而无需对内核重新编译,这在很大程度上减少了操作的复杂度。模块机制使内核预编译时不必包含很多无关功能,把内核做到最精简,后期可以根据需要进行添加。

而针对驱动程序,因为涉及到具体的硬件,很难使通用的,且其中可能包含了各个厂商的私密接口,厂商几乎不会允许开发者把源代码公开,这就和linux的许可相悖,模块机制很好的解决了这个冲突,允许驱动程序后期进行添加而不合并到内核。OK,下面结合源代码讨论下模块机制的实现。

二、模块的组成

2.1 模块加载函数<linux/init.h>

内核模块加载函数一般以_ _init 标识声明:static int _ _init initialization_function(void)
将它放在内核入口:module_init(initialization_function);

2.2 模块卸载函数<linux/init.h>

内核模块卸载函数一般以_ _exit 标识声明,static void _ _exit cleanup_function(void);
将它放在模块出口,module_exit(cleanup_function);;

2.3模块许可证<linux/module.h>

MODULE_LICENSE("GPL");     //模块许可证
 * The following license idents are currently accepted as indicating free
 * software modules
 *
 *  "GPL"               [GNU Public License v2 or later]
 *  "GPL v2"            [GNU Public License v2]
 *  "GPL and additional rights" [GNU Public License v2 rights and more]
 *  "Dual BSD/GPL"          [GNU Public License v2
 *                   or BSD license choice]
 *  "Dual MIT/GPL"          [GNU Public License v2                                                                    
 *                   or MIT license choice]
 *  "Dual MPL/GPL"          [GNU Public License v2
 *                   or Mozilla license choice]
 *
 * The following other idents are available
 *
 *  "Proprietary"           [Non free products]

2.4 模块传参

1.相关函数
(1)**module_param(name, type, perm)**  
		功能:接收加载驱动时传递的参数
		参数:
		@name :变量名字
		@type : 类型   byte, short, ushort, int, uint, long, ulong,charp,bool,invbool   ------>注意这里没有char类型      
		@perm : 权限 0664 0x775   

(2)**MODULE_PARM_DESC(_parm, desc)**  
		功能:对传递参数的描述
		参数:
		@_parm:变量名字
		@desc :写字符串描述参数

(3) module_param_named(name, value, type, perm) 
		功能:对变量重命名,传递参数是重命名
		参数:
		@name : 外部传递参数的名字,重命名的名字
		@value :重命名前的名字
		@type  :类型
		@perm:权限
(4)module_param_array(name, type, nump, perm)  
		功能:接收用户传递的数组
		参数:
		@name :数组名字
		@type :类型
		@nump :用户传递数据的个数
		@perm :权限
(5)module_param_string(name, string, len, perm) 
		功能:接收字符数组
		参数:
		@name  :数组名
		@string:数组名
		@len   :长度
		@perm  :权限

下面对上述函数实例验证:
demo.c

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

int a=10;
module_param(a,int,0644);
MODULE_PARM_DESC(a,"this is int val");

short b=14;
module_param(b,short,0771);
MODULE_PARM_DESC(b,"this is short val");

char *p = "hello kernel";
module_param(p,charp,0664);
MODULE_PARM_DESC(p,"this is string val");

int tt[5];
int num;
module_param_array(tt,int,&num,0664);
MODULE_PARM_DESC(tt,"this is array");

int pp=500;
module_param_named(ww,pp,int,0664);
MODULE_PARM_DESC(ww,"this is array");

char buf[10];
module_param_string(buf,buf,10,0664);
MODULE_PARM_DESC(buf,"this is char array");

static int __init demo_init(void)
{
	int i;
	printk("a = %d\n",a);
	printk("b = %d\n",b);
	printk("p = %s\n",p);
	printk("pp = %d\n",pp);
	printk("buf = %s\n",buf);
	for(i=0; i<num; i++){
		printk("tt[%d] = %d\n",i,tt[i]);
	}
	printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
	return 0;
}

static void __exit demo_exit(void)
{
	printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);

}

module_init(demo_init);
module_exit(demo_exit);
MODULE_LICENSE("GPL");

makefile

KERNELDIR := /lib/modules/$(shell uname -r)/build/
#KERNELDIR := /home/linux/kernel/kernel-3.4.39/
PWD := $(shell pwd)
all:
	make -C $(KERNELDIR) M=$(PWD)  modules
clean:
	make -C $(KERNELDIR) M=$(PWD)  clean

obj-m := demo.o

编译及加载:
在这里插入图片描述
a. 我们先不加任何参数加载驱动:insmod demo.o,dmesg查看打印如下:
在这里插入图片描述
b. 我们加入参数: //传递字符串是不能有空格
在这里插入图片描述
dmesg查看打印如下:
在这里插入图片描述
这里我们没有对PP变量该名称,没找到怎么修改,大家可以留言。
当权限不为0的时候,模块加载后会生成变量对应的文件,文件内容即变量值
在这里插入图片描述

2.4 导出符号

EXPORT_SYMBOL_GPL(sym)  //功能:导出符号表
int add(int a,int b)
{}
	return (a+b);
}
导出:EXPORT_SYMBOL_GPL(add);
调用:extern int add(int a,int b);
将导出者的Module.symvers拷贝到调用者的目录下,接着执行make编译调用者
执行的顺序:
	1.先执行导出者
	2.在执行调用者
卸载的顺序:
	1.先卸载调用者
	2.在卸载导出者

2. 模块声明与描述

声明:MODULE_AUTHOR 作者
MODULE_DESCRIPTION 描述
MODULE_ VERSION 版本
MODULE_DEVICE_TABLE 设备表
MODULE_ALIAS 别名

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值