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
<author@linuxdriver.cn>. 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, author@linuxdriver.cn");
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