Linux Kernel Module Parameters


Reference :
1.  http://tldp.org/LDP/lkmpg/2.6/html/x323.html
2.  http://makelinux.com/ldd3/chp-2-sect-8

前言:
        這個文章是我最近在寫Linux Kernel Device Driver遇到的問題,所以想說寫下來才不會忘記,也順便分享出來讓有需要的人更快可以上手,如果對於我寫的文章有問題或是有更好的想法,也請大家一起交流。

相關參數介紹:

        在寫Linux Kernel Module的時候,我們用insmod或 modprobe安裝的時候,可以對module填入我們想要的參數,例如:
               
            $> sudo  insmod mymod.ko number=10


       這樣的好處讓你的Kernel modules在設計的時候會比較有彈性,然後這些參數在Kernel module是經過module_param這個Macro來處理。以下是對module_param的介紹:


module_param( param name, data type, permissions bits);


 1. param name : 參數名稱
 2. data type       : 資料型態



  • bool
  • invbool
  • A boolean (true or false) value (the associated variable should be of type int). The invbool type inverts the value, so that true values become false and vice versa.
  • charp
  • A char pointer value. Memory is allocated for user-provided strings, and the pointer is set accordingly.
  • int
  • long
  • short
  • uint
  • ulong
  • ushort
3. permissions bits : The final module_param field is a permission value; you should use the definitions found in . This value controls who can access the representation of the module parameter in sysfs. If perm is set to 0, there is no sysfs entry at all
(有關參數的權限,但我還不太懂之後比較瞭解再補充。)


        再另外補充一下macro就是MODULE_PARM_DESC,這個marco主要就是讓你可以用modinfo這個工具去讀取kernel module的資訊時顯示這個module參數的資訊。以下是例子:


static short int myshort = 1;

module_param(myshort, short, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
MODULE_PARM_DESC(myshort, "A short integer");


完整的範例:


# Makefile




  obj-m += hello-5.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
                                                                       

# hello-5.c (這是由Reference 1的網頁中直接拿來做範例)



/*
 *  hello-5.c - Demonstrates command line argument passing to a module.
 */
#include 
#include 
#include 
#include 
#include 

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Peter Jay Salzman");

static short int myshort = 1;
static int myint = 420;
static long int mylong = 9999;
static char *mystring = "blah";
static int myintArray[2] = { -1, -1 };
static int arr_argc = 0;

/* 
 * module_param(foo, int, 0000)
 * The first param is the parameters name
 * The second param is it's data type
 * The final argument is the permissions bits, 
 * for exposing parameters in sysfs (if non-zero) at a later stage.
 */

module_param(myshort, short, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
MODULE_PARM_DESC(myshort, "A short integer");
module_param(myint, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(myint, "An integer");
module_param(mylong, long, S_IRUSR);
MODULE_PARM_DESC(mylong, "A long integer");
module_param(mystring, charp, 0000);
MODULE_PARM_DESC(mystring, "A character string");

/*
 * module_param_array(name, type, num, perm);
 * The first param is the parameter's (in this case the array's) name
 * The second param is the data type of the elements of the array
 * The third argument is a pointer to the variable that will store the number 
 * of elements of the array initialized by the user at module loading time
 * The fourth argument is the permission bits
 */
module_param_array(myintArray, int, &arr_argc, 0000);
MODULE_PARM_DESC(myintArray, "An array of integers");

static int __init hello_5_init(void)
{
 int i;
 printk(KERN_INFO "Hello, world 5\n=============\n");
 printk(KERN_INFO "myshort is a short integer: %hd\n", myshort);
 printk(KERN_INFO "myint is an integer: %d\n", myint);
 printk(KERN_INFO "mylong is a long integer: %ld\n", mylong);
 printk(KERN_INFO "mystring is a string: %s\n", mystring);
 for (i = 0; i < (sizeof myintArray / sizeof (int)); i++)
 {
  printk(KERN_INFO "myintArray[%d] = %d\n", i, myintArray[i]);
 }
 printk(KERN_INFO "got %d arguments for myintArray.\n", arr_argc);
 return 0;
}

static void __exit hello_5_exit(void)
{
 printk(KERN_INFO "Goodbye, world 5\n");
}

module_init(hello_5_init);
module_exit(hello_5_exit);



     $> make
     $> sudo insmod hello_5.ko

用dmesg去看一下,Kernel Module秀出什麼資訊 。
     $> dmesg


[ 6532.204976] Hello, world 5
[ 6532.204979] =============
[ 6532.204983] myshort is a short integer: 1
[ 6532.204986] myint is an integer: 420
[ 6532.204989] mylong is a long integer: 9999
[ 6532.204991] mystring is a string: blah
[ 6532.204994] myintArray[0] = -1
[ 6532.204996] myintArray[1] = -1
[ 6532.204999] got 0 arguments for myintArray.

   $> sudo rmmod hello_5.ko


   $>  sudo insmod hello_5.ko  mystring="abcde" myintArray=1,12
[ 6915.780582] Hello, world 5
[ 6915.780585] =============
[ 6915.780592] myshort is a short integer: 1
[ 6915.780597] myint is an integer: 420
[ 6915.780601] mylong is a long integer: 9999
[ 6915.780605] mystring is a string: abcde
[ 6915.780609] myintArray[0] = 1
[ 6915.780613] myintArray[1] = 12
[ 6915.780617] got 1 arguments for myintArray.

如果你想要看Kernel module的相關訊息的話,請使用:

     $> modinfo hello_5.ko


filename:       hello_5.ko
author:         Peter Jay Salzman
license:        GPL
srcversion:     A704327C32F7F311666C13C
depends:    
vermagic:       3.0.0-12-generic SMP mod_unload modversions
parm:           myshort:A short integer (short)
parm:           myint:An integer (int)
parm:           mylong:A long integer (long)
parm:           mystring:A character string (charp)
parm:           myintArray:An array of integers (array of int)

留言

熱門文章