Chinaunix首页 | 论坛 | 博客
  • 博客访问: 968380
  • 博文数量: 113
  • 博客积分: 7235
  • 博客等级: 少将
  • 技术积分: 2101
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-14 11:24
文章分类

全部博文(113)

文章存档

2013年(7)

2012年(5)

2011年(6)

2010年(8)

2009年(15)

2008年(72)

分类: LINUX

2008-07-17 12:59:51

    在进行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 file
xiyoulinux@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 来改变参数。


阅读(1968) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~