[linux内核笔记-1]内核模块参数传递----module_param()函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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/*一个字符指针值. 内存为用户提供的字串分配, 指针因此设置.*/
intlongshort
uintulongushort /*基本的变长整型值. 以 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()函数的主要内容,如果未能解决你的问题,请参考以下文章

内核模块实验奔跑吧Linux内核

Linux之module_param()--给模块传递参数

将变量从linux内核传递给进程

Linux 驱动开发-内核模块设计笔记 0

linux笔记 14课linux内核参数设定及内核编译安装

uboot想Linux内核传递参数