在进行linux内核模块编程时,常常需要给模块传递参数,其作用是从使用的设备号到驱动应当任何操作的几个方面. 例如, SCSI 适配器的驱动常常有选项控制标记命令队列的使用, IDE 驱动允许用户控制 DMA 操作. 如果你的驱动控制老的硬件, 还需要被明确告知哪里去找硬件的 I/O 端口或者 I/O 内存地址. 内核通过在加载驱动的模块时指定可变参数的值, 支持这些要求。
参数常常被声明为一个静态全局变量,如static int num=10;然后使用module_param(参数名,参数类型,参数读写权限)为模块定义一个参数,例如:
module_prarm(num,int,S_IRUGO);
这样你就可以在insmod(装载模块)的时候为参数指定值,如果没有指定则使用默认值,例如上面的num=10,则10是参数num的默认值。下面以一个例子说明:
#include #include MODULE_LICENSE("Dual BSD/GPL");
static int num=10;
module_param(num,int,S_IRUGO);
static int hello_init(void)
{
printk("Hello module init.\n");
printk("num=%d\n",num);
return 0;
}
static void hello_exit(void)
{
printk("Goodbye module exit.\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_DESCRIPTION("a simple module");
MODULE_ALIAS("hello");
将以上代码保存为文件hello.c,编写Makefile文件对其进行编译:
# Makefile2.6
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else
PWD := $(shell pwd)
KVER ?= $(shell uname -r)
KDIR := /lib/modules/$(KVER)/build
all:
$(MAKE) -C $(KDIR) M=$(PWD)
endif
然后make就可以了,make会生成:
|-- Module.symvers
|-- built-in.o
|-- hello.ko
|-- hello.mod.c
|-- hello.mod.o
`-- hello.o
这些文件,其中的hello.ko就是编译生成的模块,使用insmod将hello.ko模块装载进内核,这个需要超级用户权限,我的系统是ubuntu7.10,所以使用如下命令装载:
sudo insmod hello.ko num=20
使用dmesg命令查看运行结果:
xiyoulinux@xiyoulinux-desktop:~/module$ dmesg #实际上是读取/var/log/messages文件的内容
... #省略以前的信息
[14801.675260] Hello module init.
[14801.675265] num=20
这就是运行结果。如果你插入的是sudo insmod hello.ko,那么:使用dmesg命令查看运行结果:
xiyoulinux@xiyoulinux-desktop:~/module$ dmesg #实际上是读取/var/log/messages文件的内容
... #省略以前的信息
[14801.675260] Hello module init.
[14801.675265] num=10 #取默认值
以上是内核模块的编译和运行情况,实际上你还需要用到lsmod(查看模块是否被插入,一般在打印出来的第一行里)、rmmod(卸载装载的模块,只有当模块的引用计数为0时才能被卸载)等命令。
那么实质上当你装载模块hello.ko时,系统会在/sys/module下生成一个hello文件夹:xiyoulinux@xiyoulinux-desktop:/sys/module/hello$ tree
.
|-- holders
|-- initstate
|-- parameters
| `-- num
|-- refcnt
|-- sections
| |-- __param
| `-- __versions
`-- srcversion
3 directories, 6 files
其中parameters目录中就存放的是该模块的参数,一个参数对应一个文件,文件的内容为参数的默认值例如:
xiyoulinux@xiyoulinux-desktop:/sys/module/hello/parameters$ tree
.
`-- num
0 directories, 1 filexiyoulinux@xiyoulinux-desktop:/sys/module/hello/parameters$ cat num
10在module_param(num,int,S_IRUGO);
定义参数时,其中的参数读写权限S_IRUGO其实是对参数文件的读写权限,所以权限的设置值就和对文件的设置值一样,例如上面对num参数权限的设置S_IRUGO就是对所有用户具有读的权限,而S_IRUGO|S_IWUSR 则允许 root 来改变参数。