CodeDump : HelloParam

CodeDump :: Categories :: PageIndex :: RecentChanges :: RecentlyCommented :: Login/Register

Hello Parameter Kernel Module


up

It is still possible to extend the HelloWorld and the HelloCurrent modules. This time module parameters are introduced, these parameters
can be set when the module is installed. This can be useful to define some variables at runtime. E.g. you have ramdisk support compiled as a module but you wish to define the the size of such a ramdisk dynamically, and this in function of the amount of memory requiered. modinfo shows which parameters can be set in order to define the size of the ramdisk:

psychotic:/lib/modules/2.6.11.11/kernel/drivers/block# modinfo rd.ko 
filename:       rd.ko
alias:          block-major-1-*
license:        GPL
vermagic:       2.6.11.11 preempt K8 gcc-3.3
depends:        
parm:           rd_blocksize:Blocksize of each RAM disk in bytes. (int)
parm:           rd_size:Size of each RAM disk in kbytes. (int)


With modinfo you can get all sort of metadata about a compiled kernel module. vermagic is the kernel version which was used to compile this module (which will be checked on module insertion !). Other metadata can be set. E.g. MODULE_AUTHOR, MODULE_LICENSE, MODULE_VERSION etc, these macro's (and others) are defined in include/linux/module.h, relative to the kernel source root.
The second part of modinfo output are the parameters this module accepts. These parameters have to be defined in the module. this is done with the module_param(name, type, perm) as defined in the linux/moduleparam.h header:
/* Helper functions: type is byte, short, ushort, int, uint, long,
   ulong, charp, bool or invbool, or XXX if you define param_get_XXX,
   param_set_XXX and param_check_XXX. */

#define module_param_named(name, value, type, perm)               \
    param_check_##type(name, &(value));                   \
    module_param_call(name, param_set_##type, param_get_##type, &value, perm); \
    __MODULE_INFO(parmtype, name##type, #name ":" #type)

#define module_param(name, type, perm)                \
    module_param_named(name, name, type, perm)

So module_param(string, charp, S_IRUGO) defines a string input parameter (if string is a char *). charp is, like the others mentioned in the
snippet from moduleparam.h above, a definition of the variable to expect. The final parameter is the permission (linux/stat.h). S_IRUGO means in this case world readable. This results in the following code:

#include <linux/init.h>
#include <linux/module.h>

MODULE_LICENSE("Dual DSD/GPL");

MODULE_AUTHOR("Elie De Brauwer");
MODULE_DESCRIPTION("Says hello");

static char *name = "nobody";
static int howmany = 1;
static int onInit = 1;
static int onExit = 0;
module_param(howmany, int, S_IRUGO);
module_param(name, charp, S_IRUGO);
module_param(onInit, bool, S_IRUGO);
module_param(onExit, bool, S_IRUGO);

static int hello_init(void){
  if(onInit){
    int i;
    for(i=0;i<howmany;i++){
      printk(KERN_ALERT "Hello %s\n", name);
    }

  }
  return 0;
}

static void hello_exit(void){
  if(onExit){
    int i;
    for(i=0;i<howmany;i++){
      printk(KERN_ALERT "Goodbye %s\n", name);
    }
  }
}

module_init(hello_init);
module_exit(hello_exit);


This module shows by default on loading a single greeting to nobody:

Jun 19 17:59:34 localhost kernel: Hello nobody


But when settings the parameters:

psychotic:/home/helios/vuilbak/test/hello_par# insmod ./hello_par.ko onExit=1 onInit=1 name="root" howmany=3


The following output is generated (when looking a dmesg, the messages are writting three times):

Jun 19 18:38:46 localhost kernel: Hello root
Jun 19 18:38:46 localhost last message repeated 2 times
Jun 19 18:39:00 localhost kernel: Goodbye root
Jun 19 18:39:00 localhost last message repeated 2 times


In the code the MODULE_AUTHOR and the MODULE_DESCRIPTION were also set, these can be viewed with (again) modinfo:
psychotic:/home/helios/vuilbak/test/hello_par# modinfo ./hello_par.ko 
filename:       ./hello_par.ko
license:        Dual DSD/GPL
author:         Elie De Brauwer
description:    Says hello
vermagic:       2.6.11.11 preempt K8 gcc-3.3
depends:        
parm:           onExit:bool
parm:           onInit:bool
parm:           name:charp
parm:           howmany:int


Now you can see the parameters take the name of the variable name used by module_param(). The parameters of this module were set world readable, this can be done by using the /sys/ pseudo filesystem:

helios@psychotic:/sys/module/hello_par/parameters$ ls -hal
total 0
drwxr-xr-x  2 root root    0 2005-06-19 18:47 .
drwxr-xr-x  4 root root    0 2005-06-19 18:47 ..
-r--r--r--  1 root root 4.0K 2005-06-19 18:47 howmany
-r--r--r--  1 root root 4.0K 2005-06-19 18:47 name
-r--r--r--  1 root root 4.0K 2005-06-19 18:47 onExit
-r--r--r--  1 root root 4.0K 2005-06-19 18:47 onInit
helios@psychotic:/sys/module/hello_par/parameters$ for i in * ;do echo $i: ; cat $i; done
howmany:
3
name:
root
onExit:
Y
onInit:
Y


Now, what should happen if the default value to the string is a nullpointer and no new string is passed. In a normal situation (read: user space application) this would result in a segmentation fault and a core dump. But at this point the code is running in (unprotected kernel mode). But nothing spectacular happens:
Jun 19 19:02:07 localhost kernel: Hello <NULL>



up
Valid XHTML 1.0 Transitional :: Valid CSS :: Powered by Wikka Wakka Wiki 1.1.6.0
Page was generated in 0.9916 seconds