Linux driver module parameters-Linux Device Drivers
Module Parameters
In many cases, we expect to control our drive behavior through parameters. For example, because of different systems, to ensure good portability of our drivers, sometimes we want to control our driven behavior by passing parameters. In this way, drivers may have different behavior controls in different systems.
To meet this requirement, the kernel allows you to specify parameters for the driver, which can be dynamically changed during driver loading.
There are two main sources of parameters
Useinsmod/modprobe ./xxx.ko
Parameters are provided directly after the command line;
The modprobe command can be used to load a module from its configuration file/etc/modprobe.conf
File Read parameter value
This macro must be placed outside of any function., Usually the header of the actual source file
Module parameter transmission method
Linux kernel provides a simple framework for passing parameters to modules. It allows the driver to declare parameters, and the user specifies the corresponding value for parameters during system startup or module loading. In the driver, the parameter usage is like a global variable.
The following macro must contain header files.
Macro
module_param(name, type, perm)module_param_array(name, type, num_point, perm);module_param_named(name_out, name_in, type, perm);module_param_string(name, string, len, perm);
Parameter type
The kernel supports the following module parameter types:
Parameters |
Description |
Bool |
Boolean (true/false), the associated variable type should be int |
Intvbool |
Boolean inverse value. For example, the value is true, but the actual value is false. |
Int |
Integer |
Long |
Long Integer |
Short |
Short integer |
Uint |
Unsigned integer |
Ulong |
Unsigned long integer type |
Ushort |
Unsigned short integer |
Charp |
Character pointer type. The kernel allocates memory for the string provided by the user and sets the corresponding pointer. |
We will talk about how to pass the array type later.
Note:
If the types we need are not in the list above, the hooks in the module Code allow us to specify these types.
For more information, see moduleparam. h. All module parameters should be given a default value;
Insmod changes the parameter value only when the user explicitly sets the parameter value. The module can determine whether a given value is displayed based on the default value.
Access permission
Perm access permissions are managed in the same way as linux Files love your access permissions,
For example, 0644, or use a macro in stat. h, for example, S_IRUGO.
We encourage the use of the definition in stat. h. This value is used to control who can access the expression of module parameters in sysfs.
If 0 is specified, the corresponding items in sysfs are completely disabled. Otherwise, the module parameters appear in/sys/module and are set to the given access permission.
If S_IRUGO is specified, this parameter can be read by anyone but cannot be modified.
If S_IRUGO | S_IWUSR is specified, root is allowed to modify this value.
Note:
If a parameter is modified through sysfs, if the value of this parameter is the same for the module, but the kernel does not notify the module in any way, in most cases, we should not make module parameters writable unless we intend to detect such changes and make corresponding actions.
If you only have ko files but do not have source code, you only need to use
modinfo -p ${modulename}
You can see exactly.
What should I do if I want to change the module parameters of modules that have been loaded into the kernel? Simple, just enter
echo -n ${value} > /sys/module/${modulename}/parameters/${param}
.
Example Pass global Parameters
In the module, declare a variable (global variable) to receive the parameters passed when the user loads the module.
module_param(name, type, perm);
Parameters |
Description |
Name |
Variable name used to receive Parameters |
Type |
Parameter Data Type |
Perm |
Access visibility mask for sysfs entry systems |
Example-passing an int
These macros do not declare variables. Therefore, variables must be declared before using macros. The typical usage is as follows:
static int value = 0;module_param(value, int, 0644);MODULE_PARM_DESC(value_int, "Get an value from user...\n");
Use
sudo insmod param.ko value=100
To load
Example-pass charp
static char *string = "gatieme";module_param(string, charp, 0644);MODULE_PARM_DESC(string, "Get an string(char *) value from user...\n");
Use
sudo insmod param.ko string="hello"
The name of the variable in the module is different from the name of the parameter passed when the module is loaded.
In the previous case, the external parameter name must be the same as the internal name of the module. Is there any other binding method that can make our parameter transmission more flexible?
The variable name in the module source file is defined by module_param_named.
module_param_named(name_out, name_in, type, perm);
Parameters |
Description |
Name_out |
Parameter Name When a module is loaded |
Name_in |
Name of the variable in the module |
Type |
Parameter type |
Perm |
Access permission |
Use
static int value_in = 0;module_param_named(value_out, value_in, int, 0644);MODULE_PARM_DESC(value_in, "value_in named var_out...\n");
Load
sudo insmod param.ko value_out=200
Transfer string
When loading the module, pass the string to a global character array of the module.
module_param_string(name, string, len, perm);
Parameters |
Description |
Name |
Parameter Name When loading a module |
String |
Name of the character array inside the module |
Len |
Size of the character array inside the module |
Perm |
Access permission |
static char buffer[20] = "gatieme";module_param_string(buffer, buffer, sizeof(buffer), 0644);MODULE_PARM_DESC(value_charp, "Get an string buffer from user...\n");
Passing Arrays
When loading a module, PASS Parameters to the module array.
module_param_array(name, type, num_point, perm);
Parameters |
Description |
Name |
The array name of the module, which is also an external array name |
Type |
Data Type of the module Array |
Num_point |
Used to obtain the number of parameters that a user passes when loading a module. If it is NULL, it indicates the number of parameters that do not care about the user. |
Perm |
Access permission |
Use
static int array[3];int num;module_param_array(array, int, &num, 0644);MODULE_PARM_DESC(array, "Get an array from user...\n");
Source code of the param driver Driver source code param. c
# Include
# Include
# Include
/** Declare a variable (global variable) in the module, * used to receive the parameter passed when the user loads the module. ** module_param (name, type, perm) **/static int value = 0; module_param (value, int, 0644); MODULE_PARM_DESC (value_int, "Get an value from user... \ n ");/** the name of the variable inside the module and the parameter name passed during module loading are different ** module_param_named (name_out, name_in, type, perm) ** @ name_out: when loading a module, the parameter name * @ name_in refers to the internal variable name * @ type parameter type * @ perm access permission **/static int value_in = 0; module_param_named (value_out, value_in, int, 0644); MODULE_PARM_DESC (value_in, "value_in named var_out... \ n ");/** when loading the module, pass the string to a global character array in the module ** module_param_string (name, string, len, perm) ** @ name: when loading a module, parameter name * @ string module internal character array name * @ len module internal character array size * # perm access permission **/static char * string = NULL; module_param (string, charp, 0644); MODULE_PARM_DESC (string, "Get an string (char *) value from user... \ n "); static char buffer [20] =" gatieme "; module_param_string (buffer, buffer, sizeof (buffer), 0644); MODULE_PARM_DESC (value_charp, "Get an string buffer from user... \ n ");/** when loading a module, pass the parameter to the array of the module ** module_param_array (name, type, num_point, perm) ** @ name refers to the array name of the module, which is also an external array name * @ type refers to the Data type of the module array * @ num_point is used to obtain the number of parameters that the user passes when loading the module, * if it is NULL, it indicates that you do not care about the number of parameters passed by the user * @ perm access permission **/static int array [3]; int num; module_param_array (array, int, & num, 0644); MODULE_PARM_DESC (array, "Get an array from user... \ n "); int _ init param_module_init (void) {int index = 0; printk (" \ n --------------------- \ n "); printk (" value: % d \ n ", value); printk (" value_in: % d \ n ", value_in); printk (" string: % s \ n ", string ); printk ("buffer: % s \ n", buffer); for (index = 0; index <num; index ++) {printk ("array [% 2d]: % d \ n ", index, array [index]);} printk (" --------------------- \ n "); return 0;} void _ exit param_module_exit (void) {printk ("\ n ------------------- \ n"); printk ("exit param dobule \ n"); printk ("--------------------- \ n");} module_init (param_module_init ); module_exit (param_module_exit );
Makefile
obj-m := param.oKERNELDIR ?= /lib/modules/$(shell uname -r)/buildPWD := $(shell pwd)all: make -C $(KERNELDIR) M=$(PWD) modulesclean: make -C $(KERNELDIR) M=$(PWD) clean
Parameter Transfer Process
sudo insmod param.ko value=100 value_out=200 string="gatieme" buffer="Hello-World" array=100,200,300
Dmesg View
sudo rmmod param
Use modinfo to view parameters
modinfo -p param.ko
Dynamically modify module Parameters
First, check the parameter information of this module in the sysfs directory.
ls /sys/module/param/parameters
Dynamic Modification