Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

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

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

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

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

В версии 2.0 не имеется никакого контроля соответствия типов аргументов 6.1. Если первый символ 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 <linux/kernel.h>   /* We're doing kernel work */
#include <linux/module.h>   /* Specifically, a module */

/* Deal with CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include <linux/modversions.h>
#endif

#include <stdio.h>  /* 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:
 *
 * Prameter 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=<something>");
     printk("str2=<something>\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()
{
}



1999-05-19