您的位置:首页 > 其它

给内核模块传递参数

2010-09-28 16:35 357 查看
http://blog.chinaunix.net/u2/87570/showart_2121965.html




对于如何向模块传递参数,Linuxkernel提供了一个简单的框架。其允许驱动程序声明参数,并且用户在系统启动或模块装载时为参数指定相应值,在驱动程序里,参数的用法如同全局变量。


使用下面的宏时需要包含头文件<linux/moduleparam.h>。




通过宏module_param()定义一个模块参数:

module_param(name,type,perm);

name
既是用户看到的参数名,又是模块内接受参数的变量;


type
表示参数的数据类型,是下列之一:byte,short,ushort,int,uint,long,ulong,charp,bool,invbool;


perm
指定了在sysfs中相应文件的访问权限。
访问权限与linux文件访问权限相同的方式管理,如0644,或使用stat.h中的宏如S_IRUGO表示。


0
表示完全关闭在sysfs中相对应的项。


这些宏不会声明变量,因此在使用宏之前,必须声明变量,典型地用法如下:

staticunsignedintint_var=0;

module_param(int_var,uint,S_IRUGO);


这些必须写在模块源文件的开头部分。即int_var是全局的。也可以使模块源文件内部的变量名与外部的参数名有不同的名字,通过module_param_named()定义。
module_param_named(name,variable,type,perm);
其中name是外部可见的参数名,variable是源文件内部的全局变量名,而module_param通过module_param_named实现,只不过name与variable相同。


例如:

staticunsignedintmax_test=9;

module_param_name(maximum_line_test,max_test,int,0);


如果模块参数是一个字符串时,通常使用charp类型定义这个模块参数。内核复制用户提供的字符串到内存,并且相对应的变量指向这个字符串。


例如:

staticchar*name;

module_param(name,charp,0);


另一种方法是通过宏module_param_string()让内核把字符串直接复制到程序中的字符数组内。

module_param_string(name,string,len,perm);


这里,name是外部的参数名,string是内部的变量名,len是以string命名的buffer大小(可以小于buffer的大小,但是没有意义),perm表示sysfs的访问权限(或者perm是零,表示完全关闭相对应的sysfs项)。


例如:

staticcharspecies[BUF_LEN]

module_param_string(specifies,species,BUF_LEN,0);


如果需要传递多个参数可以通过宏module_param_array()实现。

module_param_array(name,type,nump,perm);

其中,name既是外部模块的参数名又是程序内部的变量名,type是数据类型,perm是sysfs的访问权限。指针nump指向一个整数,其值表示有多少个参数存放在数组name中。值得注意是name数组必须静态分配。


例如:

staticintfinsh[MAX_FISH];

staticintnr_fish;

module_param_array
(fish,int,&nr_fish,0444);//最终传递数组元素个数存在nr_fish中


通过宏module_param_array_named()使得内部的数组名与外部的参数名有不同的名字。


例如:

module_param_array_named(name,array,type,nump,perm);




通过宏MODULE_PARM_DESC()对参数进行说明:

staticunsignedshortsize=1;

module_param(size,ushort,0644);

MODULE_PARM_DESC(size,“Thesizeininchesofthefishingpole”

“connectedtothiscomputer.”);






说明:from
http://blog.csdn.net/iczyh/archive/2008/10/26/3149727.aspx


module_param()
和module_param_array()的作用就是让那些全局变量对insmod可见,使模块装载时可重新赋值。


module_param_array()
宏的第三个参数用来记录用户insmod时提供的给这个数组的元素个数,NULL表示不关心用户提供的个数


module_param()
和module_param_array()最后一个参数权限值不能包含让普通用户也有写权限,否则编译报错。这点可参考linux/moduleparam.h中__module_param_call()宏的定义。


字符串数组中的字符串似乎不能包含逗号,否则一个字符串会被解析成两个




一个测试用例:parm_hello.c




#include<linux/module.h>
#include<linux/moduleparam.h>
#include<linux/kernel.h>



#defineMAX_ARRAY6

staticintint_var=0;
staticconstchar*str_var="default";
staticintint_array[6];
intnarr;

module_param(int_var,int,0644);
MODULE_PARM_DESC(int_var,"Aintegervariable");



module_param(str_var,charp,0644);
MODULE_PARM_DESC(str_var,"Astringvariable");

module_param_array(int_array,int,&narr,0644);
MODULE_PARM_DESC(int_array,"Aintegerarray");

staticint__inithello_init(void)
{
inti;
printk(KERN_ALERT"Hello,myLKM.\n");
printk(KERN_ALERT"int_var%d.\n",int_var);
printk(KERN_ALERT"str_var%s.\n",str_var);

for(i=0;i<narr;i++){
printk("int_array[%d]=%d\n",i,int_array[i]);
}
return0;
}

staticvoid__exithello_exit(void)
{
printk(KERN_ALERT"Bye,myLKM.\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("ydzhang");
MODULE_DESCRIPTION("Thismoduleisaexample.");


测试:insmodparm_hello.koint_var=100str_var=helloint_array=100,200
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: