由于系统不同,驱动程序需要的参数也许会发生变化。这包括设备编号以及其他的一些用来控制驱动程序操作方式的参数。例如,用户向驱动程序传递一些硬件的的I/O端口后者I/O内存地址的位置之类的信息时就有可能会用到内核参数。
内核允许对驱动程序指定参数,这些参数在装载驱动程序模块时可以改变的。
以前面第二节中的hello.c为例:
改变后的hello.c:
#include <linux/moduleparam.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static char *whom = "world";
static int howmany = 1;
module_param(howmany,int,S_IRUGO);
module_param(whom,charp,S_IRUGO);
static int hello_init(void)
{
int i=0;
for(;i<howmany;i++)
printk(KERN_ALERT "Hello,%s/n",whom);
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye,cruel %s/n",whom);
}
module_init(hello_init);
module_exit(hello_exit);
Makefile不变,然后编译并装载模块:
insmod hello.ko howmany=10 whom="Mom"
则可以打印十次“hello,Mom”。
如果屏幕上不显示的话,在/var/log/message中看最后几行。
上面例子中,insmod改变参数之前,模块必须让这些参数对insmod命令可见。参数必须使用module_param宏来声明,这个宏在moduleparam.h(/usr/src/kernels/linux-2.6.30/include/linux/moduleparam.h)中定义。module_param需要三个参数:变量的名称、类型以及用于sysfs入口项的访问许可掩码。而这个宏必须放在任何函数之外,通常是在源码文件的头部。
内核支持的模块参数类型:
bool //布尔值(true/false),关联的变量应该是int型。
invbool //invbool的值取bool的反值。
charp //字符指针,内核会为用户提供的字符串分配内存,并设置指针
int
long
short
uint //无符号值
ulong
ushort
数组参数:
module_param_array(name,type,num,perm);
name:数组名,type:数组元素类型,num:会被设置为用户提供的值的个数,这个值不可超过内核可接受值。perm:是常见的可访问许可值。
module_param中的最后一个成员是访问许可值,在<linux/stat.h>中定义,她用来控制谁能够访问sysfs中对模块参数的表述。如其为0则不会有相应的sysfs访问入口项。