Linux设备驱动开发详解-第4章(二)-模块参数

1 module_param

  在用户态下编程可以通过main()的来传递命令行参数,而编写一个内核模块则通过module_param()
  参数用 module_param 宏定义来声明, 它定义在moduleparam.h.
  module_param(name,type,perm);
  module_param 使用了 3 个参数: 变量名, 它的类型, 以及一个权限掩码用来做一个辅助的 sysfs 入口(啥意思). 这个宏定义应当放在任何函数之外, 典型地是出现在源文件的前面.定义如:

staticchar *whom = "world";  
  module_param(howmany, int, S_IRUGO);
     static int howmany = 1;
  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 字段是一个权限值; 你应当使用<linux/stat.h>中定义的值. 这个值控制谁可以存取这些模块参数在 sysfs 中的表示.如果 perm 被设为 0, 就根本没有 sysfs 项. 否则, 它出现在 /sys/module下面, 带有给定的权限. 使用 S_IRUGO 作为参数可以被所有人读取, 但是不能改变; S_IRUGO|S_IWUSR允许 root 来改变参数. 注意, 如果一个参数被 sysfs 修改, 你的模块看到的参数值也改变了, 但是你的模块没有任何其他的通知. 你应当不要使模块参数可写, 除非你准备好检测这个改变并且因而作出反应。

 

2 实例验证

现在编写一个book.c实例来验证模块参数传递

2.1 book.c文件

/*======================================================================
    A kernel module: book
    This example is to introduce module params
    The initial developer of the original code is Baohua Song
    <[email protected]>. All Rights Reserved.
======================================================================*/ 
#include <linux/init.h>                                
#include <linux/module.h> 
                               
MODULE_LICENSE("Dual BSD/GPL");                                 
static char *book_name = "dissecting Linux Device Driver";              
static int num = 4000;                                
                                
static int book_init(void)                                
{                                
	printk(KERN_INFO " book name:%s\n",book_name);                        
	printk(KERN_INFO " book num:%d\n",num);                                
	return 0;                                
}                                 
static void book_exit(void)                                 
{                                
	printk(KERN_INFO " Book module exit\n ");                            
}                                 
module_init(book_init);                                
module_exit(book_exit);                                 
module_param(num, int, S_IRUGO);                                
module_param(book_name, charp, S_IRUGO); 
                                 
MODULE_AUTHOR("Song Baohua, [email protected]");
MODULE_DESCRIPTION("A simple Module for testing module params");
MODULE_VERSION("V1.0");

2.2 Makfile文件

#ifneq ($(KERNELRELEASE),)
obj-m := book.o
#else
KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

default:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
#endif

clean:
	rm -f *.ko *.mod.c *.mod.o *.o *.markers *.order *.symvers

2.3 不带参数加载模块

(1)加载模块

[root@localhost book]# insmod book.ko

[root@localhost book]# dmesg | tail -2

输出信息如下所示:

 book name:dissecting Linux Device Driver

 book num:4000

或者用tail -n 2/var/log/messages

[root@localhost book]# tail -n 2/var/log/messages

则输出信息为:

Oct 24 00:46:40 localhost kernel: bookname:dissecting Linux Device Driver

Oct 24 00:46:40 localhost kernel: booknum:4000

(2)卸载模块

[root@localhost book]# rmmod book

[root@localhost book]# dmesg | tail -4

 book name:dissecting Linux Device Driver

 book num:4000

 Book module exit

 

2.4带参数加载模块

(1)加载模块

[root@localhost book]# insmod book.kobook_name='GoodBook' num=5000

[root@localhost book]# dmesg | tail -2

[root@localhost book]# dmesg | tail -2

 输出信息

bookname:GoodBook

 book num:5000

(2)卸载模块

[root@localhost book]# rmmod book

[root@localhost book]# dmesg | tail -4

 book name:dissecting Linux Device Driver

 book num:4000

 Book module exit

 

3 拓展

       模块被加载后,在/sys/module/目录下将出现以此模块名命名的目录。当“参数读/写权限”为0 时,表示此参数不存在sysfs 文件系统下对应的文件节点,如果此模块存在“参数读/写权限”不为0 的命令行参数,在此模块的目录下还将出现parameters目录,包含一系列以参数名命名的文件节点,这些文件的权限值就是传入module_param()的“参数读/写权限”,而文件的内容为参数的值。

(1)加载模块

[root@localhostbook]# insmod book.ko book_name='LuckyBook' num=5000

[root@localhost book]# dmesg | tail -2

 bookname:LuckyBook

 booknum:5000

[root@localhost book]# ls -l /sys/module/book/

total 0

drwxr-xr-x. 2 root root    0 Oct 24 00:57 holders

-r--r--r--. 1 root root 4096 Oct 24 00:57 initstate

drwxr-xr-x. 2 root root    0 Oct 24 00:57 notes

drwxr-xr-x. 2 root root    0 Oct 24 00:57 parameters

-r--r--r--. 1 root root 4096 Oct 24 00:57 refcnt

drwxr-xr-x. 2 root root    0 Oct 24 00:57 sections

-r--r--r--. 1 root root 4096 Oct 24 00:57srcversion

-r--r--r--. 1 root root 4096 Oct 24 00:57 version    

[root@localhost book]# ls /sys/module/book/parameters/

book_name num

[root@localhost book]# cat /sys/module/book/parameters/book_name

LuckyBook

[root@localhost book]# cat /sys/module/book/parameters/num

5000

参考文献

[1] 宋宝华. Linux设备驱动开发详解

[2] 百度百科. http://baike.baidu.com/view/4212836.htm





你可能感兴趣的:(编程,linux,shell,Module,Parameters,testing)