1. symptom description
In Linux systems, dynamic Loading modules often need to be implemented:
1) when loading a module, pass a parameter value to the module, and the parameter value cannot be modified during the module operation;
2) When loading a module, pass a parameter value to the module, and the parameter value is dynamically modified as needed during the module operation.
2. Key Processes
1. In the Linux system 2.6 kernel, you can use the macro module_param (name, type, Perm) to declare the parameter name as a module parameter, which can be specified during module loading, otherwise, it is the default value defined in the module;
2. We need to pay attention to perm. Perm indicates the attributes of this parameter in the file node of the sysfs File System:
1) When perm is 0, this parameter indicates that the file node does not exist in the sysfs file system;
2) After the module is loaded, the directory named after this module will appear under the/sys/module/directory;
3) If this module has a command line parameter whose perm Is not 0, the parameters directory will appear under the directory of this module, containing a series of file nodes named after parameters;
4) The permission value of these files is equal to perm, and the file content is the parameter value.
3. perm has four module parameters with different attributes:
1) read/write parameter: this parameter can be viewed in real time and its value can be dynamically modified; its attribute is s_irugo | s_iwusr;
2) readable parameter: this parameter can only be viewed in real time and cannot be dynamically modified. Its attribute is s_irugo;
3) writable parameter: this parameter cannot be viewed in real time, but can be dynamically modified; its attribute is s_iwusr;
4) Non-read/write parameter: this parameter cannot be displayed in the sysfs file system, nor can it be viewed and dynamically modified in real time; its attribute value is 0;
Therefore, we can set different perm values to control different parameters.
3. Case implementation
3.1. Demo description
1. the demo program defines two parameters for each module: UID and period. When loading a module, you can pass the values of these two parameters to the module. Otherwise, the values of these two parameters will be the default values, both can be read by the user, user group, and other groups, and the latter can be modified by the user.
2. Meanings of perm permission values used by the demo program:
S_irugo: s_irusr | s_irgrp | s_iroth, which indicates that it can be read and read by the user, user group, and other groups;
S_iwusr: indicates that it can be modified by the user (the user who can dynamically load the module must be a Super User.
3. the demo program prints different information based on the UID and period. When the period value changes, the information is printed again.
4. the demo program is described as follows:
1) when loading the module: insmod demo. Ko uid = 0 period = 0
2) When the module is running, read the UID value: CAT/sys/module/demo/parameters/uid
3) when the module is running, modify the period value: Echo 1>/sys/module/demo/parameters/Period
3.2. Source File
# Include <Linux/kernel. h> <br/> # include <Linux/types. h> <br/> # include <Linux/spinlock. h> <br/> # include <Linux/interrupt. h> <br/> # include <Linux/delay. h> <br/> # include <Linux/blkdev. h> <br/> # include <Linux/list. h> <br/> # include <Linux/Timer. h> <br/> # include <Linux/version. h> <br/> # include <Linux/moduleparam. h> <br/> # include <Linux/device. h> <br/> # include <Linux/module. h> <br/> # include <Linux/string. H> <br/> # include <Linux/dma-mapping.h> <br/> # include <ASM/semaphore. h> <br/> # include <ASM/page. h> <br/> typedef uint8_t bool_t; </P> <p> # define morning 0 <br/> # define afternoon 1 <br/> # define evening 2 <br/> # define unknown 3 </P> <p> # define false 0 <br/> # define true 1 </P> <p> # define user_num 3 </P> <p> /******* * module information ***************/<br/> module_author ("H3C Corporation "); <br/> module_descript Ion ("demo function"); <br/> module_license ("GPL "); </P> <p>/********* module parameters ******************/<br/> static uint uid = 0; <br/> module_param (UID, uint, s_irugo); </P> <p> static uint period = morning; <br/> module_param (period, uint, s_irugo | s_iwusr ); </P> <p>/********* global parameters ******************/<br/> char user_name [user_num] [20] = {"wuwu "}, {"pikaqiu" },{ "Lala" }}; <br/> uint prev_period = UN Known; <br/> bool_t demo_quit = false; <br/> struct completion com_demo; </P> <p> int demo_thread (void * unuse) <br/>{< br/> daemonize ("demo_thread"); </P> <p> (;;) <br/>{< br/> If (demo_quit) <br/>{< br/> break; <br/>}</P> <p> If (prev_period! = Period) <br/>{< br/> If (morning = period) <br/>{< br/> printk (kern_emerg "Good morning, % s/n ", user_name [uid]); <br/>}< br/> else if (afternoon = period) <br/> {<br/> printk (kern_emerg "Good afternoon, % s/n", user_name [uid]); </P> <p >}< br/> else if (evening = period) <br/> {<br/> printk (kern_emerg "Good evening, % s/n ", user_name [uid]); <br/>}< br/> else <br/>{< br/> printk (kern_emerg" par Ameter period is invalid! Please choose from follows:/N "); <br/> printk (kern_emerg" 0: means morning/N "); <br/> printk (kern_emerg" 1: means afternoon/N "); <br/> printk (kern_emerg" 2: means evening/N "); <br/> printk (kern_emerg"/N "); <br/>}</P> <p> prev_period = period; <br/>}</P> <p> msleep (10 ); <br/>}</P> <p> complete_and_exit (& com_demo, 0 ); <br/>}</P> <p> static int _ init demo_init (void) <br/>{< br/> pid_t pid = 0; <br/> Uint32_t I = 0; </P> <p> If (UID> = user_num) <br/> {<br/> printk (kern_emerg "parameter uid is invalid, please choose from follows:/N "); <br/> for (I = 0; I <user_num; I ++) <br/>{< br/> printk (kern_emerg "I: named % s/n", user_name [I]); <br/>}< br/> printk (kern_emerg "/N"); </P> <p> return-1; <br/>}</P> <p> init_completion (& com_demo); <br/> pid = kernel_thread (demo_thread, null, clone_kernel); <br/> If (PID <0) <br/>{< br/> printk (kern_emerg "demo thread create failed! /N "); <br/> return-1; <br/>}</P> <p> printk (kern_emerg" welcome to the demo! /N "); <br/> return 0; <br/>}</P> <p> static void _ exit demo_exit (void) <br/>{< br/> demo_quit = true; <br/> wait_for_completion (& com_demo); <br/> printk (kern_emerg "Byebye, % s/n ", user_name [uid]); <br/> return; <br/>}</P> <p> module_init (demo_init); <br/> module_exit (demo_exit );
4. Experience Summary
1. Set the perm bit based on different user permission requirements;
2. If you only need to pass the parameter value when loading the module and do not want the user to see the parameter, we recommend that you set the perm position to 0.