Linux - статьи

Передача модулю параметров командной строки


Имеется возможность передачи модулю дополнительных параметров командной строки, но делается это не с помощью 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


Содержание раздела