Monday, March 3, 2014

How to Pass Command Line Arguments to a Kernel Module?

Generally the word command line arguments make you strike to argc/argv in C, here coming to Linux kernel modules approach is bit different and even easy to....!! lets go for a walk on this concept.

To allow arguments to be passed to your module, declare the variables that will take the values of the command line arguments as global and then use the module_param()macro, defined in linux/moduleparam.h to set the mechanism up.
Value is assigned to this variable at runtime by a command line arguments that are given like$ insmod mymodule.ko myvariable=5 while inserting/loading the module into kernel.

The variable declarations and macros should be placed at the beginning of the module for clarity.

In this post Loadable Kernel Module i have explained the basic concepts of kernel modules.

The module_param() macro takes 3 arguments: 
  • arg1 : The name of the variable.
  • arg2 : Its type
  • arg3 : Permissions for the corresponding file in sysfs. 
Example Code Snippet :

static int myint =51;
module_param(myint, int, 0);
MODULE_PARM_DESC(myint,"this is the int variable");

Integer types can be signed as usual or unsigned. 

MODULE_PARM_DESC() macro used for giving the description of variable.
Example for all the data types are given below:
static int dint;
module_param(dint, int, 0);
MODULE_PARM_DESC(dint,"this is the dynamic int variable");

static short myshort = 51;
module_param(myshort, short, 0);
MODULE_PARM_DESC(myshort,"this is the short variable");
static long int mylong = 45100;
module_param(mylong, long , 0);
MODULE_PARM_DESC(myshort,"this is the long int variable");

static char *mychar = "Smack Down";
module_param(mychar, charp, 0);
MODULE_PARM_DESC(myshort,"this is the characte string variable");

static int myarr[2] = {51,43};
static int arr_argc = 0;
module_param_array(myarr, int,&arr_argc, 0);
MODULE_PARM_DESC(myarr,"this is the array variable");

Example Code:

Code: 
#include <linux/kernel.h> /*needed for priority messages in prink*/
#include <linux/init.h> /*needed for macros*/
#include <linux/module.h> /*needed for all modules*/

MODULE_LICENSE("GPL");
MODULE_AUTHOR("xyz");
MODULE_DESCRIPTION("Test Module Parameters");

static short myshort = 51;
static int myint = 451;
static int dint;
static long int mylong = 45100;
static char *mychar = "Smack Down";
static int myarr[2] = {51,43};
static int arr_argc = 0;
static int hello_world2_data __initdata = 3;

module_param(dint, int, 0);
MODULE_PARM_DESC(dint,"this is the dynamic int variable");

module_param(myshort, short, 0);
MODULE_PARM_DESC(myshort,"this is the short variable");

module_param(myint, int, 0);
MODULE_PARM_DESC(myint,"this is the int variable");


module_param(mylong, long , 0);
MODULE_PARM_DESC(myshort,"this is the long int variable");


module_param(mychar, charp, 0);
MODULE_PARM_DESC(myshort,"this is the characte string variable");


module_param_array(myarr, int,&arr_argc, 0);
MODULE_PARM_DESC(myarr,"this is the array variable");

int __init hello_world2_init(void){
 int i;
 printk(KERN_INFO "Vamshi : Entered2 : data = %d",hello_world2_data);
 printk(KERN_INFO "Value of the the short variable is = %hd",myshort);
 printk(KERN_INFO "Value of the the short variable is = %d",myint);
 printk(KERN_INFO "Value of the the dint variable is = %d",dint);
 printk(KERN_INFO "Value of the the short variable is = %ld",mylong);
 printk(KERN_INFO "Value of the the short variable is = %s",mychar);
 for(i=0;i<sizeof(myarr)/sizeof(int);i++){
  printk(KERN_INFO "arr[%d] = %d\n",i,myarr[i]);
 }
 return 0;
}
void __exit hello_world2_exit(void){
 printk(KERN_INFO "abc : Exited2 ");
}

module_init(hello_world2_init);
module_exit(hello_world2_exit);





Note: Copying the code directly into your source.c file will also copies the invisible characters and finally you will left out with stray errors, i recommend you to type the code and that even becomes a practice.
Makefile:
obj-m := hello_world2.o
all:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean




Use Cases of Module Parameters:
  • When there is a need to change the irq line of the module then its the best way to pass the irq number as command line argument using module parameter concept.
  • Base address of the register map of a module can be passed at module load time using insmod based on this command line arguments.

No comments:

Post a Comment