module_param&&MODULE_PARM_DESC

来源:互联网 发布:百度负面网络公关 编辑:程序博客网 时间:2024/05/17 04:17
module_param&&MODULE_PARM_DESC
2011-02-09 17:15

在用户态下编程可以通过main()的来传递命令行参数,而编写一个内核模块则通过module_param()
module_param宏是Linux2.6内核中新增的,该宏被定义在include/linux/moduleparam.h文件中,具体定义如下:
#definemodule_param(name, type, perm)
module_param_named(name,name, type, perm)

其中使用了3 个参数:要传递的参数变量名, 变量的数据类型, 以及访问参数的权限。
module_param(name,type,perm);
module_param使用了 3 个参数: 变量名, 它的类型, 以及一个权限掩码用来做一个辅助的 sysfs 入口(啥意思).这个宏定义应当放在任何函数之外, 典型地是出现在源文件的前面.定义如:
staticchar *whom = "world";
staticint howmany = 1;
module_param(howmany, int, S_IRUGO);
module_param(whom, charp, S_IRUGO);
模块参数支持许多类型:
bool
invbool
一个布尔型(true 或者 false)值(相关的变量应当是 int 类型). invbool 类型颠倒了值, 所以真值变成 false,反之亦然.
charp
一个字符指针值.内存为用户提供的字串分配, 指针因此设置.
int
long
short
uint
ulong
ushort
基本的变长整型值.以 u 开头的是无符号值.

数组参数,用逗号间隔的列表提供的值, 模块加载者也支持. 声明一个数组参数, 使用:

module_param_array(name,type,num,perm);
这里name 是你的数组的名子(也是参数名),
type是数组元素的类型,
num是一个整型变量,
perm是通常的权限值.
如果数组参数在加载时设置,num 被设置成提供的数的个数. 模块加载者拒绝比数组能放下的多的值.

perm参数的作用是什么?
最后的module_param 字段是一个权限值; 你应当使用 中定义的值. 这个值控制谁可以存取这些模块参数在 sysfs 中的表示.如果perm 被设为 0, 就根本没有 sysfs 项. 否则, 它出现在 /sys/module下面, 带有给定的权限. 使用S_IRUGO 作为参数可以被所有人读取, 但是不能改变; S_IRUGO|S_IWUSR 允许 root 来改变参数. 注意,如果一个参数被 sysfs 修改, 你的模块看到的参数值也改变了, 但是你的模块没有任何其他的通知. 你应当不要使模块参数可写,除非你准备好检测这个改变并且因而作出反应.
perm参数的作用是什么?
最后的module_param 字段是一个权限值,表示此参数在sysfs文件系统中所对应的文件节点的属性。你应当使用 中定义的值.这个值控制谁可以存取这些模块参数在 sysfs 中的表示.当perm为0时,表示此参数不存在 sysfs文件系统下对应的文件节点。否则, 模块被加载后,在/sys/module/ 目录下将出现以此模块名命名的目录,带有给定的权限.。
权限在include/linux/stat.h中有定义
比如:
#defineS_IRWXU 00700
#defineS_IRUSR 00400
#defineS_IWUSR 00200
#defineS_IXUSR 00100
#defineS_IRWXG 00070
#defineS_IRGRP 00040
#defineS_IWGRP 00020
#defineS_IXGRP 00010
#defineS_IRWXO 00007
#defineS_IROTH 00004
#defineS_IWOTH 00002
#defineS_IXOTH 00001
使用S_IRUGO 作为参数可以被所有人读取, 但是不能改变; S_IRUGO|S_IWUSR 允许 root 来改变参数. 注意,如果一个参数被 sysfs 修改, 你的模块看到的参数值也改变了, 但是你的模块没有任何其他的通知. 你应当不要使模块参数可写,除非你准备好检测这个改变并且因而作出反应.

通过宏MODULE_PARM_DESC()对参数进行说明:
static unsigned short size 1;
module_param(size, ushort, 0644);
MODULE_PARM_DESC(size, “The size in inches of the fishing pole”
“connected to this computer.” );

 

 

 

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";
static int int_array[6];
intnarr;

module_param(int_var,int,0644);
MODULE_PARM_DESC(int_var,"Ainteger variable");


module_param(str_var,charp,0644);
MODULE_PARM_DESC(str_var,"Astring variable");

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

staticint__inithello_init(void)
{
       inti;
       printk(KERN_ALERT"Hello,world.\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,world.\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("kelly");
MODULE_DEION("Thismodule is a example.");

 

 

测试:insmod parm_hello.koint_var=100str_var=helloint_array=100,200

0 0