模块可以接受命令行参数,但不是使用您可能熟悉的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'