[linux內核筆記-1]內核模塊參數傳遞----module_param()函數


/* @author = s1n */

/*文中出現的源碼均來自linux 3.16.41內核*/

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(test, 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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM