模块可以接受命令行参数,但不是使用您可能熟悉的argc/argv方式。
要允许将参数传递给您的模块,请将用于接收命令行参数值的变量声明为全局变量,然后使用MODULE_PARM()宏(定义在linux/module.h中)来设置机制。在运行时,insmod 将使用给定的任何命令行参数填充变量,例如 ./insmod mymodule.o myvariable=5。为了清晰起见,变量声明和宏应放置在模块的开头。示例代码应该可以消除我承认糟糕的解释。
该MODULE_PARM()宏接受 2 个参数:变量的名称及其类型。支持的变量类型有 “b”: 单字节,“h”: short int,“i”: integer,“l”: long int 和 “s”: 字符串,并且整数类型可以像往常一样是有符号的或无符号的。字符串应声明为 “char *”,insmod 将为其分配内存。您应该始终尝试为变量提供初始默认值。这是内核代码,您应该防御性地编程。例如
int myint = 3;
char *mystr;
MODULE_PARM(myint, "i");
MODULE_PARM(mystr, "s");
也支持数组。MODULE_PARM 中类型前面的整数值将指示某个最大长度的数组。用 “-” 分隔的两个数字将给出值的最小和最大数量。例如,一个至少有 2 个且不超过 4 个值的 short 数组可以声明为
int myshortArray[4];
MODULE_PARM (myintArray, "3-9i");
一个好的用途是设置模块变量的默认值,例如端口或 IO 地址。如果变量包含默认值,则执行自动检测(在其他地方解释)。否则,保持当前值。稍后将对此进行说明。
最后,还有一个宏函数,MODULE_PARM_DESC(),用于记录模块可以接受的参数。它接受两个参数:变量名和一个描述该变量的自由格式字符串。
示例 2-7. hello-5.c
/* hello-5.c - Demonstrates command line argument passing to a module.
*
* Copyright (C) 2001 by Peter Jay Salzman
*
* 08/02/2006 - Updated by Rodrigo Rubira Branco <rodrigo@kernelhacking.com>
*/
/* Kernel Programming */
#define MODULE
#define LINUX
#define __KERNEL__
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Peter Jay Salzman");
// These global variables can be set with command line arguments when you insmod
// the module in.
//
static u8 mybyte = 'A';
static unsigned short myshort = 1;
static int myint = 20;
static long mylong = 9999;
static char *mystring = "blah";
static int myintArray[2] = { 0, 420 };
/* Now we're actually setting the mechanism up -- making the variables command
* line arguments rather than just a bunch of global variables.
*/
MODULE_PARM(mybyte, "b");
MODULE_PARM(myshort, "h");
MODULE_PARM(myint, "i");
MODULE_PARM(mylong, "l");
MODULE_PARM(mystring, "s");
MODULE_PARM(myintArray, "1-2i");
MODULE_PARM_DESC(mybyte, "This byte really does nothing at all.");
MODULE_PARM_DESC(myshort, "This short is *extremely* important.");
// You get the picture. Always use a MODULE_PARM_DESC() for each MODULE_PARM().
static int __init hello_5_init(void)
{
printk(KERN_ALERT "mybyte is an 8 bit integer: %i\n", mybyte);
printk(KERN_ALERT "myshort is a short integer: %hi\n", myshort);
printk(KERN_ALERT "myint is an integer: %i\n", myint);
printk(KERN_ALERT "mylong is a long integer: %li\n", mylong);
printk(KERN_ALERT "mystring is a string: %s\n", mystring);
printk(KERN_ALERT "myintArray is %i and %i\n", myintArray[0], myintArray[1]);
return 0;
}
static void __exit hello_5_exit(void)
{
printk(KERN_ALERT "Goodbye, world 5\n");
}
module_init(hello_5_init);
module_exit(hello_5_exit);我建议试用一下这段代码
satan# insmod hello-5.o mystring="bebop" mybyte=255 myintArray=-1
mybyte is an 8 bit integer: 255
myshort is a short integer: 1
myint is an integer: 20
mylong is a long integer: 9999
mystring is a string: bebop
myintArray is -1 and 420
satan# rmmod hello-5
Goodbye, world 5
satan# insmod hello-5.o mystring="supercalifragilisticexpialidocious" \
> mybyte=256 myintArray=-1,-1
mybyte is an 8 bit integer: 0
myshort is a short integer: 1
myint is an integer: 20
mylong is a long integer: 9999
mystring is a string: supercalifragilisticexpialidocious
myintArray is -1 and -1
satan# rmmod hello-5
Goodbye, world 5
satan# insmod hello-5.o mylong=hello
hello-5.o: invalid argument syntax for mylong: 'h'