|
设备驱动程序通常使用固定的内部变量值,而由源代码指定该变量。根据具体情况,还可在运行设备驱动程序之前修改变量。如在 linux系统启动时,在选择系统菜单的下方可以看到视频参数的设置 ---这类参数属于初始化变量,可在加载或卸载模块时进行修改。通常利用 bootloader 的选项功能或模块的实用程序 insmod 命令调整为内核命令模式。
设备驱动程序的初始化参数中外部能够修改的变量称作模块变量。设备驱动程序创建为模块后,利用以下 insmod 命令可以指定变量:insmod ./test.ko onevalue=0x27 twostring="Oh my god!"
由 insmod 命令指定模块变量,而模块插入内核时处理该变量。
2.4 内核中使用模块变量实例:
#include <linux/module.h>
#include <linux/kernel.h>
static int onevalue = 1;
static char *twostring = NULL;
MODULE_PARM (onevalue, "i");
MODULE_PARM (twostring, "s");
int init_module (void)
{
printk ("Hello world [onevalue=%d:twostring=%s]\n", onevalue, twostring);
return 0;
}
void cleanup_module (void)
{
printk ("Goodbye world\n");
} 由于本机是基于 2.6 内核的 opensuse11.1 ,所以 2.4 内核环境选择在华恒的一块开发板上做这个测试。对于这个程序,直接在命令行里编译:beyes@linux-beyes:~/C/hh2410/module_test> /opt/host/armv4l/bin/armv4l-unknown-linux-gcc -D__KERNEL__ -DMODULE -Wall -O2 -I/HHARM2410-STUDY/kernel/include/ -c test.c -o test.o 编译后,把 test.o 所在文件夹通过 NFS 服务器共享出去,然后通过 minicom 连接到开发板,接着在开发板上把文件拷贝到根目录,然后执行:insmod test.o onevalue=0x27 twostring="Oh my god" 用 dmesg 看到输出:Hello world [onevalue=39:twostring]=Oh my god 说明:
MODULE_PARM 宏的语法如下:
MODULE_PARM (变量名, 变量类型) 扩展
[变量类型]
MODULE_PARM 宏不能定义变量,所以如果需要这个宏来传递命令行参数,那么就需要在模块中定义一个全局变量。在 insmod 模块时,就可以使用参数的形式,将具体的实参传递给模块中的那个全局变量。MODULE_PARM(name, type)的两个参数,一个是全局变量的名称,另一个就是上面所示的变量类型。
在传递字符串类型的参数时,全局变量需要在模块中使用 char * 来声明,insmod 会自动为其分配内存空间。
MODULE_PARM() 也支持数组类型。用短线 '-' 把两个数字分开,分别表示数组中的最小位数和最大位数。比如:
int a[5];
MODULE_PARM(a, "1-5i");
2.6 内核模块变量使用实例:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
static int onevalue = 1;
static char *twostring = NULL;
module_param (onevalue, int, 0);
module_param (twostring, charp, 0);
static int hello_init (void)
{
printk ("Hello, world [onevalue=%d:twostring=%s]\n", onevalue, twostring);
return 0;
}
static void hello_exit (void)
{
printk ("Goodbye, world\n");
}
module_init (hello_init);
module_exit (hello_exit);
MODULE_LICENSE ("Dual BSD/GPL"); 编译后,加载到内核并随即卸载:beyes@linux-beyes:~/C/hh2410/module_test> sudo /sbin/insmod test26.ko onevalue=0x27 twostring="hello,baby"
beyes@linux-beyes:~/C/hh2410/module_test> sudo /sbin/rmmod test26.ko 注意,在 2.6 内核中,字符串参数不能有空格,否则出错!如:beyes@linux-beyes:~/C/hh2410/module_test> sudo /sbin/insmod test26.ko onevalue=0x27 twostring="hello baby"
insmod: error inserting 'test26.ko': -1 Unknown symbol in module 查看内核输出信息:Hello, world [onevalue=39:twostring=hello,baby]
Goodbye, world
............. ................ .............. ............... ............. ...................
与 2.4 内核不同,2.6 内核中使用模块变量时应包含 linux/moduleparam.h 头文件。
2.6 内核中用 module_param 宏代替 2.4 内核中使用过的 MODULE_PARM 宏。
module_param 宏语法格式:
module_param (变量名, 变量类型, 使用属性)
[变量类型]
[使用属性]
除了特殊情况,通常把文件结点属性指定为 0。该参数用来设置用户的访问权限,普通用户能在内核上加载模块的几率很少。如果一定要设置结点,可用文件权限 (permission) 等概念指定 0644 等八进制数。 |
|