PASS Parameters from the command line to the kernel module (module_parm)

Source: Internet
Author: User

Http://blog.chinaunix.net/u1/54524/showart_470321.html

The module can also obtain parameters from the command line. But it's not something you usedArgc/Argv.

To pass a parameter to the module, declare the variable that obtains the parameter value as a global variable. Then use the macroMODULE_PARM()(In the header fileLinux/module. h). At runtime, insmod will assign the command line parameters to the variables, just./Insmod mymodule. O myvariable = 5. To make the code clearer, both the Declaration and macro of variables should be placed at the beginning of the module code. The following code examples may be better than I agree.

MacroMODULE_PARM()Two parameters are required, the variable name and its type. Supported types include"B": Bit type ,"H": Short integer ,"I": Integer type ,"L: Long integer and"S": String type. The positive value can be either signed or unsigned. The string type should be declared as "char *" so that insmod can allocate memory space for them. You should always assign initial values to your variables. This is kernel programming, and the code should be very careful. For example:

int myint = 3;
char *mystr;

MODULE_PARM(myint, "i");
MODULE_PARM(mystr, "s");

Arrays are also supported. The integer value before the type symbol in the macro module_parm means an array with the maximum length specified. The two numbers separated by '-' mean the minimum length and the maximum length respectively. In the following example, an integer array with a minimum length of 2 and a maximum length of 4 is declared.

int myshortArray[4];
MODULE_PARM (myintArray, "3-9i");

Setting the initial value to the default I/O port or I/O memory is a good practice. If these variables have default values, you can perform automatic device detection. Otherwise, keep the current value. We will explain the relevant content in subsequent chapters. Here I just demonstrate how to pass parameters to a module.

Finally, there is such a macro,MODULE_PARM_DESC()It is used to annotate the parameters that can be received by this module. The macro has two parameters: the variable name and a free description of the variable.

Example 2-7. hello-5.c

/*
* hello-5.c - Demonstrates command line argument passing to a module.
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/stat.h>

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";

/*
* 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");

static int __init hello_5_init(void)
{
printk(KERN_ALERT "Hello, world 5/n=============/n");
printk(KERN_ALERT "myshort is a short integer: %hd/n", myshort);
printk(KERN_ALERT "myint is an integer: %d/n", myint);
printk(KERN_ALERT "mylong is a long integer: %ld/n", mylong);
printk(KERN_ALERT "mystring is a string: %s/n", mystring);
return 0;
}

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

module_init(hello_5_init);
module_exit(hello_5_exit);

I suggest using the following method to experiment with your module:

Satan # insmod hello-5.o mystring = "Bebop" mybyte = 255 myintarray =-1
Mybyte is an 8-bit integer: 255
Myshort is a short INTEGER: 1
Myint is an integer: 20
Mylong is a long integer: 9999
Mystring is a string: bebop
Myintarray is-1 and 420.

Satan # rmmod hello-5
Goodbye, world 5

Satan # insmod hello-5.o mystring = "supercalifragilisticexpialidocious "/
> Mybyte = 256 myintarray =-1,-1
Mybyte is an 8-bit integer: 0
Myshort is a short INTEGER: 1
Myint is an integer: 20
Mylong is a long integer: 9999
Mystring is a string: supercalifragilisticexpialidocious
Myintarray is-1 and-1

Satan # rmmod hello-5
Goodbye, world 5

Satan # insmod hello-5.o mylong = Hello
Hello-5.o: invalid argument syntax for mylong: 'H'

Module_param (name, type, Perm) is a macro that transmits parameters to the current module. The source code analysis is as follows:

In include/Linux/moduleparam. H

# Define module_param (name, type, Perm )/
Module_param_named (name, name, type, Perm)

# 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_parm_type (name, # type)



# Define module_param_call (name, set, get, ARG, Perm )/
_ Module_param_call (module_param_prefix, name, set, get, ARG, Perm)


# DEFINE _ module_param_call (prefix, name, set, get, ARG, Perm )/
/* Default value instead of permissions? *//
Static int _ param_perm_check _ # name _ attribute _ (unused) =/
Build_bug_on_zero (Perm) <0 | (Perm)> 0777 | (Perm) & 2 ));/
Static char _ param_str _ # name [] = prefix # name ;/
Static struct kernel_param const _ Param _ # name/
_ Attribute_used __/
_ Attribute _ (unused ,__ section _ ("_ Param"), aligned (sizeof (void *))))/
= {_ Param_str _ # name, Perm, set, get, Arg}



_ Atti1__ _ is a keyword of GCC. For details, refer
Http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Variable-Attributes.html
_ Attivity _ compile the parameter into the _ Param segment,

Module_param is expanded step by step,
The preceding macros are in the opposite order in include/Linux/moduleparam. h.

The order in which module_param macro calls similar functions
Module_param-> module_param_named-> module_param_call->__ module_param_call

The order of expansion is the opposite.
_ Module_param_call-> module_param_named-> module_param



The type can be byte, short, ushort, Int,
Uint, long, ulong, CHARP (Note: character pointer), bool, invbool,
Perm indicates the attributes of this parameter in the file node corresponding to the sysfs file system.
Permission defined in include/Linux/STAT. h
For example:
# Deprecision s_irwxu 00700
# Define s_irusr 00400
# Define s_iwusr 00200
# Define s_ixusr 00100

# Define s_irwxg 00070
# Define s_irgrp 00040
# Define s_iwgrp 00020
# Define s_ixgrp 00010

# Define s_irwxo 00007
# Define s_iroth 00004
# Define s_iwoth 00002
# Define s_ixoth 00001

When the perm value is 0, this parameter does not exist in the file node of the sysfs file system.
After the module is loaded, the directory named after this module appears under the/sys/module/directory.


Test, insert a driver module MP. Ko,
Sudo insmod MP. Ko
MP folder found in/sys/Module
MP has Drivers/, sections/, parameters/, initstate, refcnt, srcversion

The content in initstate is live.
Refcnt content: 0
The content in srcversion is f9bdebf706329b443c28e08. It is very long and should be a unique number.
The driver folder is empty.
Sections has _ Param ,__ versions
The content in _ Param is 0xd081e0a8.
The content in _ versions is 0xd081e100.

Parameters has count and Info (Note: Custom parameters)
The content in count is 1 (Note: Number of output times)
The content in info is a site about Linux driver. (Note: Output content)


If this module has a command line parameter whose perm Is not 0,
The parameters directory appears under the directory of this module,
Contains a series of file nodes named after parameters,
The permission value of these files is equal to perm, and the file content is the parameter value.


Parameters that appear in/sys/module/MP/correspond to the following in the module structure:
Struct module
{
Enum module_state state;

/* Member of List of modules */
Struct list_head list;

......

/* Sysfs stuff .*/
Struct module_kobject mkobj;
Struct module_param_attrs * param_attrs;
Struct module_attribute * modinfo_attrs;
Const char * version;
Const char * srcversion;
Struct kobject * drivers_dir;

/* Exported symbols */
Const struct kernel_symbol * Syms;
Unsigned int num_syms;
Const unsigned long * CRCs;

......

/* Section attributes */
Struct module_sect_attrs * sect_attrs;
# Endif

......
};


Enum module_state
{
Module_state_live,
Module_state_coming,
Module_state_going,
};

State corresponds to/sys/module/MP/initstate
Drivers_dir corresponds to the/sys/module/MP/driver folder.
Version corresponds to/sys/module/MP/sections/_ version
Srcversion corresponds to/sys/module/MP/srcversion


Test module. The content of the source program MP. C is as follows:


# Include <Linux/module. h>
# Include <Linux/moduleparam. h>

Static char * info = "A site about Linux Driver .";
Static int COUNT = 1;
Static int MP = 0;

Module_param (MP, Int, 0 );

Module_param (count, Int, s_irusr );

Module_param (Info, CHARP, s_irusr );

Module_author ("ioctrl ");
Module_license ("dual BSD/GPL ");

Static int hello_init (void)
{
Int I;
For (I = 0; I <count; I ++)
{
Printk (kern_noticewww.linuxdriver.cn is ");
Printk (Info );
Printk ("/N ");
}
Return 0;
}

Static void hello_exit (void)
{
Printk (kern_notice "exit! /N ");
}

Module_init (hello_init );
Module_exit (hello_exit );

Compile

Manual insertion: The insert parameters COUNT = 10, info = "are passed to drive the development website. "
The command is as follows:
Sudo insmod MP. Ko COUNT = 10 info = "drive the development website. "
Then use dmesg to view the message
10 records are displayed as follows.
[16122.280000] www.linuxdriver.cn is driver development website
[16122.280000] www.linuxdriver.cn is driver development website
[16122.280000] www.linuxdriver.cn is driver development website
[16122.280000] www.linuxdriver.cn is driver development website
[16122.280000] www.linuxdriver.cn is driver development website
[16122.280000] www.linuxdriver.cn is driver development website
[16122.280000] www.linuxdriver.cn is driver development website
[16122.280000] www.linuxdriver.cn is driver development website
[16122.280000] www.linuxdriver.cn is driver development website
[16122.280000] www.linuxdriver.cn is driver development website


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.