next up previous contents index
Next: System Calls Up: Linux Kernel Module Programming Previous: Talking to Device Files

     
Startup Parameters

In many of the previous examples, we had to hard-wire something into the kernel module, such as the file name for /proc files or the major device number for the device so we can have ioctl's to it. This goes against the grain of the Unix, and Linux, philosophy which is to write flexible program the user can customize.  

The way to tell a program, or a kernel module, something it needs before it can start working is by command line parameters. In the case of kernel modules, we don't get argc and argv -- instead, we get something better. We can define global variables in the kernel module and insmod will fill them for us.    

In this kernel module, we define two of them: str1 and str2. All you need to do is compile the kernel module and then run insmod str1=xxx str2=yyy. When init_module is called, str1 will point to the string `xxx' and str2 to the string `yyy'.  

In version 2.0 there is no type checking on these arguments6.1. If the first character of str1 or str2 is a digit the kernel will fill the variable with the value of the integer, rather than a pointer to the string. If a real life situation you have to check for this.  

On the other hand, in version 2.2 you use the macro MACRO_PARM to tell insmod that you expect a parameters, its name and its type. This solves the type problem and allows kernel modules to receive strings which begin with a digit, for example.    

ex 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()
{
}


next up previous contents index
Next: System Calls Up: Linux Kernel Module Programming Previous: Talking to Device Files

1999-05-19