module_param、 MODULE_PARM_DESC 、EXPORT_SYMBOL

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

其中使用了 3 个参数:要传递的参数变量名, 变量的数据类型, 以及访问参数的权限。
module_param (name,type,perm);
module_param 使用了 3 个参数: 变量名, 它的类型, 以及一个权限掩码用来做一个辅助的 sysfs 入口(啥意思). 这个宏定义应当放在任何函数之外, 典型地是出现在源文件的前面.定义如:
static char *whom = "world";
static int 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中有定义
比如:
#define S_IRWXU 00700
#define S_IRUSR 00400
#define S_IWUSR 00200
#define S_IXUSR 00100
#define S_IRWXG 00070
#define S_IRGRP 00040
#define S_IWGRP 00020
#define S_IXGRP 00010
#define S_IRWXO 00007
#define S_IROTH 00004
#define S_IWOTH 00002
#define S_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_ARRAY 6

staticintint_var=0;
staticconstchar*str_var="default";
static int int_array[6];
intnarr;

module_param(int_var,int,0644);
MODULE_PARM_DESC(int_var,"A integer variable");


module_param(str_var,charp,0644);
MODULE_PARM_DESC(str_var,"A string variable");

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

staticint__init hello_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__exit hello_exit(void)
{
       printk(KERN_ALERT"Bye, world./n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("kelly");
MODULE_DEION("This module is a example.");

Linux中EXPORT_SYMBOL的用法


EXPORT_SYMBOL标签内定义的函数对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用。您还可以手工修改内核源代码来导出另外的函数,用于重新编译并加载新内核后的测试。


Linux symbol export method:

[1] If we want export the symbol in a module, just use the EXPORT_SYMBOL(xxxx) in the C or H file.
    And compile the module by adding the compile flag -DEXPORT_SYMTAB.
    Then we can use the xxxx in the other module.


[2] If we want export some symbol in Kernel that is not in a module such as xxxx in the /arch/ppc/fec.c.
    Firstly, define the xxxx
in the fec.c;
    Secondly, make a new file which contain the "extern" define the
xxxx(for example, extern int xxxx
);
    Lastly, in the ppc_ksyms.c we includes the new file, and add the EXPORT_SYMBOL(
xxxx
).
    Then we can use the
xxxx.

你可能感兴趣的:(linux,String,Module,File,测试,Integer)