首页 > 代码库 > [linux内核笔记-1]内核模块参数传递----module_param()函数
[linux内核笔记-1]内核模块参数传递----module_param()函数
1.module_param()的定义
module_param()宏是Linux 2.6内核中新增的,该宏被定义在include/linux/moduleparam.h文件中,定义如下
1 /** 2 * module_param - typesafe helper for a module/cmdline parameter 3 * @value: the variable to alter, and exposed parameter name. 4 * @type: the type of the parameter 5 * @perm: visibility in sysfs. 6 * 7 * @value becomes the module parameter, or (prefixed by KBUILD_MODNAME and a 8 * ".") the kernel commandline parameter. Note that - is changed to _, so 9 * the user can use "foo-bar=1" even for variable "foo_bar". 10 * 11 * @perm is 0 if the the variable is not to appear in sysfs, or 0444 12 * for world-readable, 0644 for root-writable, etc. Note that if it 13 * is writable, you may need to use kparam_block_sysfs_write() around 14 * accesses (esp. charp, which can be kfreed when it changes). 15 * 16 * The @type is simply pasted to refer to a param_ops_##type and a 17 * param_check_##type: for convenience many standard types are provided but 18 * you can create your own by defining those variables. 19 * 20 * Standard types are: 21 * byte, short, ushort, int, uint, long, ulong 22 * charp: a character pointer 23 * bool: a bool, values 0/1, y/n, Y/N. 24 * invbool: the above, only sense-reversed (N = true). 25 */ 26 27 #define module_param(name, type, perm) 28 module_param_named(name, name, type, perm) 29 30 31 /** 32 * module_param_named - typesafe helper for a renamed module/cmdline parameter 33 * @name: a valid C identifier which is the parameter name. 34 * @value: the actual lvalue to alter. 35 * @type: the type of the parameter 36 * @perm: visibility in sysfs. 37 * 38 * Usually it‘s a good idea to have variable names and user-exposed names the 39 * same, but that‘s harder if the variable must be non-static or is inside a 40 * structure. This allows exposure under a different name.
41 */
原型:module_param(name, type, perm);
参数:
,name:既是用户看到的参数名,又是模块内接受参数的变量;;
,type:表示参数的类型;
,perm:指定了在sysfs中相应文件的访问权限;
这个宏定义应当放在任何函数之外, 典型地是出现在源文件的前面.定义如
static char *whom = "world"; static int howmany = 1; module_param (howmany, int, S_IRUGO); module_param (whom, charp, S_IRUGO); /*使用 S_IRUGO 作为参数可以被所有人读取*/
2.module_param()支持的类型:
bool,invbool /*一个布尔型( true 或者 false)值(相关的变量应当是 int 类型). invbool 类型颠倒了值, 所以真值变成 false, 反之亦然.*/ charp/*一个字符指针值. 内存为用户提供的字串分配, 指针因此设置.*/ int,long,short uint,ulong,ushort /*基本的变长整型值. 以 u 开头的是无符号值.*/
4.prem参数:
该参数在include/linux/stat.h中给出定义
/*include/linux/stat.h */ #ifndef _LINUX_STAT_H #define _LINUX_STAT_H #include <asm/stat.h> #include <uapi/linux/stat.h> #define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO) #define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO) #define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH) #define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH) #define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH) #define UTIME_NOW ((1l << 30) - 1l) #define UTIME_OMIT ((1l << 30) - 2l) /*uapi/linux/stat.h */ #ifndef _UAPI_LINUX_STAT_H #define _UAPI_LINUX_STAT_H #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) #define S_IFMT 00170000 #define S_IFSOCK 0140000 #define S_IFLNK 0120000 #define S_IFREG 0100000 #define S_IFBLK 0060000 #define S_IFDIR 0040000 #define S_IFCHR 0020000 #define S_IFIFO 0010000 #define S_ISUID 0004000 #define S_ISGID 0002000 #define S_ISVTX 0001000 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) #define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) #define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) #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 #endif #endif /* _UAPI_LINUX_STAT_H */
最后的 module_param 字段是一个权限值,表示此参数在sysfs文件系统中所对应的文件节点的属性。你应当使用 中定义的值. 这个值控制谁可以存取这些模块参数在 sysfs 中的表示.当perm为0时,表示此参数不存在 sysfs文件系统下对应的文件节点。 否则, 模块被加载后,在/sys/module/ 目录下将出现以此模块名命名的目录, 带有给定的权限。
5.对参数的描述方法:
通过通过宏MODULE_PARM_DESC()对参数进行说明:
static unsigned short test = 1; module_param(size, ushort, 0644); MODULE_PARM_DESC(size, “this param is a test”);
7.module_param_named()
原型:module_param_named(name, variable, type, perm);
其中name是外部可见的参数名,variable是源文件内部的全局变量名,而module_param通过module_param_named实现,此时name与variable相同。该方法可以使模块源文件内部的变量名与外部的参数名有不同的名字。
例如:
static unsigned int max_test = 9; module_param_named(maximum_line_test, max_test, int, 0); /*此定义下,该参数的外部可见参数名为:maximum_line_test,* * 内部全局变量名为:max_test */ module_param(max_test,int,0); /*此定义下,该参数的外部可见参数名为:max_test,* * 内部全局变量名为:max_test */
8.其它衍生的方法:
原型:module_param_array(name, type, nump, perm);
参数:
,name:既是用户看到的参数名,又是模块内接受参数的变量;;
,type:表示参数的类型;
,nump:指针,指向一个整数,其值表示有多少个参数存放在数组name中。值得注意是name数组必须静态分配
,perm:指定了在sysfs中相应文件的访问权限;
例:
static int finsh[MAX_FISH]; static int nr_fish; module_param_array(fish, int, &nr_fish, 0444); //最终传递数组元素个数存在nr_fish中
原型:module_param_string(name, string, len, perm);
参数:
,name:既是用户看到的参数名,又是模块内接受参数的变量;;
,string:是内部的变量名
,nump:以string命名的buffer大小(可以小于buffer的大小,但是没有意义)
,perm:指定了在sysfs中相应文件的访问权限;
例:
static char species[BUF_LEN]; module_param_string(specifies, species, BUF_LEN, 0);
9.引导模块时传递参数:
# insmod module.ko [param1=value param2=value ...]
10.实例
/*hello.c*/
1 #include <linux/module.h> 2 #include <linux/moduleparam.h> 3 #include <linux/kernel.h> 4 5 #define MAX_ARRAY 6 6 7 static int int_var = 0; 8 static const char *str_var = "default"; 9 static int int_array[6]; 10 int narr; 11 12 module_param(int_var, int, 0644); 13 MODULE_PARM_DESC(int_var, "A integer variable"); 14 15 module_param(str_var, charp, 0644); 16 MODULE_PARM_DESC(str_var, "A string variable"); 17 18 module_param_array(int_array, int, &narr, 0644); 19 MODULE_PARM_DESC(int_array, "A integer array"); 20 21 22 static int __init hello_init(void) 23 { 24 int i; 25 printk(KERN_ALERT "Hello, my LKM.\n"); 26 printk(KERN_ALERT "int_var %d.\n", int_var); 27 printk(KERN_ALERT "str_var %s.\n", str_var); 28 29 for(i = 0; i < narr; i ++){ 30 printk("int_array[%d] = %d\n", i, int_array[i]); 31 } 32 return 0; 33 } 34 35 static void __exit hello_exit(void) 36 { 37 printk(KERN_ALERT "Bye, my LKM.\n"); 38 } 39 module_init(hello_init); 40 module_exit(hello_exit); 41 MODULE_LICENSE("GPL"); 42 MODULE_AUTHOR("ydzhang"); 43 MODULE_DEION("This module is a example.");
makefile文件:
### Makefile obj-m := hello.o KERNEL_DIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules clean: $(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
[linux内核笔记-1]内核模块参数传递----module_param()函数