内核提供了一个简单的框架:
允许模块声明模块参数。
可以在内核启动,或者模块加载的时候指定参数的值。
提供/sys/module/<module>/parameters/<parameter>接口来读取和修改模块参数的值。
内核还提供模块参数cb,来在设置和读取的时候,调用一个cb,来实现对参数进行校验,执行一个动作等。
由于参数的数据类型很多,内核提供了几个宏来声明参数
1 module_param(name, type, perm)
name是模块参数的变量名,type是变量的数据类型,perm是参数的权限,和文件的权限一样,如0644。
static int allow_live_bait = 1;
module_param(allow_live_bait, bool, 0644);
linux/moduleparam.h,注释了详细的类型,有:
byte, hexint, short, ushort, int, uint, long, ulong,
charp
bool
invbool
charp是字符串指针。
2 module_param_named(name, variable, type, perm)
模块参数的名可以和变量名不同
3 module_param_string(name, string, len, perm)
定义一个字符串数组模块参数。
static char species[BUF_LEN];
module_param_string(specifies, species, BUF_LEN, 0);
4 module_param_array(name, type, nump, perm)
可以传递一个逗号分开的值给一个数组参数。
static int fish[MAX_FISH];
static int nr_fish;
module_param_array(fish, int, &nr_fish, 0444);
类似的有一个 module_param_array_named(name, array, type, nump, perm);
最后还可以指定模块参数的描述信息
static unsigned short size = 1;
module_param(size, ushort, 0644);
MODULE_PARM_DESC(size, "The size in inches of the fishing pole " \
"connected to this computer.");
modinfo可以参考模块的信息,也包括参数信息:
$ modinfo -p mymodule.ko
debug:debug level (int)
内核会将模块参数导出到sysfs,路径如下:
/sys/module/<module name>/parameters/<parameter name>
可以进行读写,例如:
$ sudo insmod mymodule.ko
$ sudo cat /sys/module/mymodule/parameters/debug
0
$ sudo sh -c "echo 1 > /sys/module/mymodule/parameters/debug"
有些特殊的场景,比如校验模块参数的值,修改参数的时候执行一个动作等。
此时就需要自定义参数的读写函数:
1 2 3 4 5 6 7 8 9 10 | struct kernel_param_ops { /* How the ops should behave */ unsigned int flags; /* Returns 0, or -errno. arg is in kp->arg. */ int (*set)( const char *val, const struct kernel_param *kp); /* Returns length written or -errno. Buffer is 4k (ie. be short!) */ int (*get)( char *buffer, const struct kernel_param *kp); /* Optional function to free kp->arg when module unloaded. */ void (* free )( void *arg); }; |
这里就不再赘述了。
注意,如果修改内核模块参数,可能需要使用 kernel_param_lock()来保护数据。
比如charp参数,内核会分配和释放。
参考
https://devarea.com/linux-kernel-development-kernel-module-parameters/
http://books.gigatux.nl/mirror/kerneldevelopment/0672327201/ch16lev1sec6.html