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

Во многих из предыдущих примеров, мы жестко задавали какие-либо параметры в модуле. Это идет против правил 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