module_param

module_param()用法  

在用户态下编程可以通过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 个参数:要传递的参数变量名, 变量的数据类型, 以及访问参数的权限。

<<<

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 修改, 你的模块看到的参数值也改变了, 但是你的模块没有任何其他的通知. 你应当不要使模块参数可写, 除非你准备好检测这个改变并且因而作出反应.

>>>

这个宏定义应当放在任何函数之外, 典型地是出现在源文件的前面.定义如:

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 被设置成提供的数的个数. 模块加载者拒绝比数组能放下的多的值. 测试模块,源程序hello.c内容如下: #include  #include
#include          MODULE_LICENSE("Dual BSD/GPL");    

static char *who= "world";            
static int times = 1;       
module_param(times,int,S_IRUSR);    
module_param(who,charp,S_IRUSR);  

static int hello_init(void)      
{
    int i;
    for(i=0;i        printk(KERN_ALERT "(%d) hello, %s!\n",i,who);
     return 0;
}

static void hello_exit(void)
{
    printk(KERN_ALERT"Goodbye, %s!\n",who);
}

module_init(hello_init);
module_exit(hello_exit);

编译生成可执行文件hello

插入: # insmod hello who="world" times=5 出现5次"hello,world!": #(1)hello,world! #(2)hello,world! #(3)hello,world! #(4)hello,world! #(5)hello,world! 卸载: # rmmod hello 出现: #Goodbye,world!

device driver也可以像用户态程序一样在运行开始时传入参数,例如argc和argv。

  • module_param(name, type, perm)   
  • module_param_array(name, type, nump, perm)   
  • module_param_cb(name, ops, arg, perm)   

此外,module_param还会在/sys/module/下面创建对应的节点,可以查看有哪些数值是可供查询或修改的。

其定义在include/linux/moduleparam.h中。

权限参数perm的定义如下:

    • S_IWUSR
    • S_IRUSR
    • S_IXUSR
    • S_IRGRP
    • S_IWGRP
    • S_IXGRP

In this S_I is a common header.
R = read ,W =write ,X= Execute.
USR =user ,GRP =Group
Using OR ‘|’ (or operation) we can set multiple permissions at a time.

参数type支持的类型如下:

  • bool
  • invbool: A boolean (true or false) value (the associated variable should be of type int). The invbool type inverts the value, so that true values become false and vice versa.
  • charp:A char pointer value. Memory is allocated for user-provided strings, and the pointer is set accordingly.
  • int
  • long
  • short
  • uint
  • ulong
  • ushort

module_param

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

static char *sysfs_string= "my_sysfs_test_string";

static int sysfs_int= 111;

static long sysfs_long= 222;

static short sysfs_short= 333;

static unsigned int sysfs_uint= 444;

static unsigned long sysfs_ulong= 555;

static unsigned short sysfs_ushort= 666;

static bool sysfs_bool= 777;

static bool sysfs_invbool= 888;

module_param(sysfs_string, charp, 00644);

module_param(sysfs_int, int, 00644);

module_param(sysfs_long, long, 00644);

module_param(sysfs_short, short, 00644);

module_param(sysfs_uint, uint, 00644);

module_param(sysfs_ulong,ulong, 00644);

module_param(sysfs_ushort,ushort, 00644);

module_param(sysfs_bool,bool, 00644);

module_param(sysfs_invbool,invbool, 00644);

module_param_array

1

2

static int sysfs_int_array[]= {1,2,3,4,5,6,7,8};

module_param_array(sysfs_int_array, int, NULL, S_IRUSR|S_IWUSR);

 参数nump表示array的大小,可选项。默认设置为NULL即可。

module_param_cb

如果在设定或读取参数时,需要进行类似通知等操作,可以使用module_param_cb,在get或set时调用对应的回调函数。module_param_array和module_param调用的是默认的回调函数, module_param_cb支持自定义回调函数。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

static int cb_valueETX = 999;

int notify_param(const char *val, const struct kernel_param *kp)

{

        int res = param_set_int(val, kp); // Use helper for write variable

        if(res==0) {

                printk(KERN_INFO "Call back function called...\n");

                printk(KERN_INFO "New value of cb_valueETX = %d\n", cb_valueETX);

                return 0;

        }

        return -1;

}

  

const struct kernel_param_ops my_param_ops =

{

        .set = ¬ify_param, // Use our setter ...

        .get = ¶m_get_int, // .. and standard getter

};

  

module_param_cb(cb_valueETX, &my_param_ops, &cb_valueETX, S_IRUGO|S_IWUSR );

 全部代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

#include

#include

#include

#include

#include

static char *sysfs_string= "my_sysfs_test_string";

static int sysfs_int= 111;

static long sysfs_long= 222;

static short sysfs_short= 333;

static unsigned int sysfs_uint= 444;

static unsigned long sysfs_ulong= 555;

static unsigned short sysfs_ushort= 666;

static bool sysfs_bool= 777;

static bool sysfs_invbool= 888;

module_param(sysfs_string, charp, 00644);

module_param(sysfs_int, int, 00644);

module_param(sysfs_long, long, 00644);

module_param(sysfs_short, short, 00644);

module_param(sysfs_uint, uint, 00644);

module_param(sysfs_ulong,ulong, 00644);

module_param(sysfs_ushort,ushort, 00644);

module_param(sysfs_bool,bool, 00644);

module_param(sysfs_invbool,invbool, 00644);

static int sysfs_int_array[]= {1,2,3,4,5,6,7,8};

module_param_array(sysfs_int_array, int, NULL, S_IRUSR|S_IWUSR);

  

/*----------------------Module_param_cb()--------------------------------*/

static int cb_valueETX = 999;

int notify_param(const char *val, const struct kernel_param *kp)

{

        int res = param_set_int(val, kp); // Use helper for write variable

        if(res==0) {

                printk(KERN_INFO "Call back function called...\n");

                printk(KERN_INFO "New value of cb_valueETX = %d\n", cb_valueETX);

                return 0;

        }

        return -1;

}

  

const struct kernel_param_ops my_param_ops =

{

        .set = ¬ify_param, // Use our setter ...

        .get = ¶m_get_int, // .. and standard getter

};

  

module_param_cb(cb_valueETX, &my_param_ops, &cb_valueETX, S_IRUGO|S_IWUSR );

/*-------------------------------------------------------------------------*/

static int mytest_init(void)

{

    printk("sysfs_buff=%s\n", sysfs_string);

    return 0;

}

static void mytest_exit(void)

{

}

module_init(mytest_init);

module_exit(mytest_exit);

MODULE_LICENSE("GPL");

你可能感兴趣的:(Linux学习,udp)