Загрузочные параметры

Во многих из предыдущих примеров, мы жестко задавали какие-либо параметры в модуле. Это идет против правил Unix и Linux, философия которых такова, что программа должна быть гибкой, чтобы пользователь мог ее настраивать.

Способ сообщить программе или модулю что-либо до запуска это параметры командной строки. В случае ядерных модулей, мы не получаем argc и argv. Вместо этого, мы получаем кое-что лучше. Мы можем определять глобальные переменные в модуле, и insmod заполнит их для нас.

В этом ядерном модуле мы определяем две таких переменных: str1 и str2. Все, что Вы должны делать это скомпилировать модуль и затем выполнить insmod str1=xxx str2=yyy. При вызове init_module str1 укажет на строку `xxx' и str2 на строку `yyy'.

В версии 2.0 не имеется никакого контроля соответствия типов аргументов[6]. Если первый символ str1 или str2 является цифрой, ядро заполнит переменную значением целого числа, а не указателем на строку. В реальной ситуации Вы должны проверять это.

С другой стороны, в версии 2.2 Вы используете макрокоманду MACRO_PARM , чтобы сообщить insmod, что Вы ожидаете параметры, их имена и их типы. Это решает проблему типа и позволяет модулям получать строки, которые начинаются с цифры.

param.c

/* param.c 

* 

* Receive command line parameters at module installation 

*/ 

/* Copyright (C) 1998-99 by Ori Pomerantz */ 


/* The necessary header files */ 

/* Standard in kernel modules */ 

#include  /* We're doing kernel work */ 

#include  /* Specifically, a module */ 


/* Deal with CONFIG_MODVERSIONS */ 

#if CONFIG_MODVERSIONS==1 

#define MODVERSIONS 

#include  

#endif 


#include  /* I need NULL */ 


/* In 2.2.3 /usr/include/linux/version.h includes a 

* macro for this, but 2.0.35 doesn't - so I add it 

* here if necessary. */ 

#ifndef KERNEL_VERSION 

#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c)) 

#endif 


/* Emmanuel Papirakis: 

* 

* Parameter names are now (2.2) handled in a macro. 

* The kernel doesn't resolve the symbol names 

* like it seems to have once did. 

* 

* To pass parameters to a module, you have to use a macro 

* defined in include/linux/modules.h (line 176). 

* The macro takes two parameters. The parameter's name and 

* it's type. The type is a letter in double quotes. 

* For example, "i" should be an integer and "s" should 

* be a string. */ 

char *str1, *str2; 


#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) 

MODULE_PARM(str1, "s"); 

MODULE_PARM(str2, "s"); 

#endif 


/* Initialize the module - show the parameters */ 

int init_module() {

 if (str1 == NULL || str2 == NULL) {

 printk("Next time, do insmod param str1=");

 printk("str2=\n");

 } else printk("Strings:%s and %s\n", str1, str2); 

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

 printk("If you try to insmod this module twice,");

 printk("(without rmmod'ing\n");

 printk("it first), you might get the wrong");

 printk("error message:\n");

 printk("'symbol for parameters str1 not found'.\n"); 

#endif

 return 0; 

} 


/* Cleanup */ 

void cleanup_module() { } 

Загрузка...