Передача модулю параметров командной строки
Имеется возможность передачи модулю дополнительных параметров командной строки, но делается это не с помощью argc/argv.
Для начала вам нужно объявить глобальные переменные, в которые будут записаны входные параметры, а затем вставить макрос MODULE_PARAM(), для запуска механизма приема внешних аргументов. Значения параметров могут быть переданы модулю с помощью команд insmod или modprobe. Например: insmod mymodule.ko myvariable=5. Для большей ясности, объявления переменных и вызовы макроопределений следует размещать в начале модуля. Пример кода прояснит мое, по общему признанию, довольно неудачное объяснение.
Макрос MODULE_PARAM() принимает 2 аргумента: имя переменной и ее тип. Поддерживаются следующие типы переменных
"b" -- byte (байт);
"h" -- short int (короткое целое);
"i" -- integer (целое, как со знаком, так и без знака);
"l" -- long int (длинное целое, как со знаком, так и без знака);
"s" -- string (строка, должна объявляться как char*).
Для переменных типа char *, insmod будет сама выделять необходимую память. Вы всегда должны инициализировать переменные значениями по-умолчанию, не забывайте -- это код ядра, здесь лучше лишний раз перестраховаться. Например:
int myint = 3; char *mystr;
MODULE_PARAM(myint, "i"); MODULE_PARAM(mystr, "s");
Параметры-массивы так же допустимы. Целое число, предшествующее символу типа аргумента, обозначает максимальный размер массива. Два числа, разделенные дефисом -- минимальное и максимальное количество значений. Например, массив целых, который должен иметь не менее 2-х и не более 4-х значений, может быть объявлен так:
int myintArray[4]; MODULE_PARAM(myintArray, "2-4i");
Желательно, чтобы все входные параметры модуля имели значения по-умолчанию, например адреса портов ввода-вывода. Модуль может выполнять проверку переменных на значения по-умолчанию и если такая проверка дает положительный результат, то переходить к автоматическому конфигурированию (вопрос автонастройки будет обсуждаться ниже).
И, наконец, еще одно макроопределение -- MODULE_PARAM_DESC(). Оно используется для описания входных аргументов модуля. Принимает два параметра: имя переменной и строку описания, в свободной форме.
Пример 2-7. hello-5.c
/* * hello-5.c - Пример передачи модулю аргументов командной строки. */ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/stat.h>
MODULE_LICENSE("GPL"); MODULE_AUTHOR("Peter Jay Salzman");
static short int myshort = 1; static int myint = 420; static long int mylong = 9999; static char *mystring = "blah";
/* * module_param(foo, int, 0000) * Первый параметр -- имя переменной, * Второй -- тип, * Последний -- биты прав доступа * для того, чтобы выставить в sysfs * (если ненулевое значение) на более поздней стадии. */
module_param(myshort, short, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); MODULE_PARM_DESC(myshort, "A short integer"); module_param(myint, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); MODULE_PARM_DESC(myint, "An integer"); module_param(mylong, long, S_IRUSR); MODULE_PARM_DESC(mylong, "A long integer"); module_param(mystring, charp, 0000); MODULE_PARM_DESC(mystring, "A character string");
static int __init hello_5_init(void) { printk(KERN_ALERT "Hello, world 5\n=============\n"); printk(KERN_ALERT "myshort is a short integer: %hd\n", myshort); printk(KERN_ALERT "myint is an integer: %d\n", myint); printk(KERN_ALERT "mylong is a long integer: %ld\n", mylong); printk(KERN_ALERT "mystring is a string: %s\n", mystring); 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" myshort=255 myshort is a short integer: 255 myint is an integer: 420 mylong is a long integer: 9999 mystring is a string: bebop
satan# rmmod hello-5 Goodbye, world 5
satan# insmod hello-5.o mystring="supercalifragilisticexpialidocious" myint=100 myshort is a short integer: 1 myint is an integer: 100 mylong is a long integer: 9999 mystring is a string: supercalifragilisticexpialidocious
satan# rmmod hello-5 Goodbye, world 5
satan# insmod hello-5.o mylong=hello hello-5.o: `hello' invalid for parameter mylong