01-内核模块传参
内核模块在insmod时允许传递参数,来实现更灵活的需求。例如:在调试内核模块时,可能需要控制该模块的日志输出等级,来方便分析模块的问题。普通的做法是代码中有一个变量控制日志等级,修改编译后加载模块。
但是如果通过传递参数的方式来修改日志等级,就无需修改和重新编译了。
linux内核通过宏module_param来实现内核传参。该宏来自include/linux/moduleparam.h
#define module_param(name, type, perm) \
module_param_named(name, name, type, perm)
该宏接受3个参数name、type、perm。它实际的作用是把模块中的一个变量name修饰为可参数的变量。用法如下:
static int itype=0;
module_param(itype,int,S_IRUGO)
//或者直接用8进制的数值表示权限
module_param(itype,int,0644)
- name:要修饰的变量名
- type:变量类型。类型包括byte、short、ushort、int、uint、long、ulong,指针类型charp,布尔类型bool,反布尔类型invbool。布尔类型支持任意数值(0:false,其他:true)或者,y/n、Y/N等形式
- perm:sysfs中参数文件的可见性。如果模块支持内核传参,那么加载模块后在
/sys/module/your_module_name/parameters/目录下,会生成一个和参数名同名的文件,这里的权限就相当于该文件的读写权限。通常不允许设置执行权限,我在4.9.88内核上实测发现设置了执行权限会被强制清掉可执行的bit位,并且insmod时还会提示警告。特别的,如果权限设置为全0,那么你将看不到这个文件,甚至如果你只定义了一个可传参参数,你会连parameters目录都看不到。如果参数有可写权限,那么访问该参数时,最好用kernel_param_lock和kernel_param_unlock包裹相关语句,这其实是个数据竞态问题,可能存在多线程访问。
除了module_param外,还有针对数组的module_param_array和针对字符串的module_param_string。
使用insmod传递参数时,每个参数以key=value形式传递,对于数组类型,多个value间以,隔开,不同的参数间又是以空格分隔。
下面是测试验证程序:
#include <linux/module.h>
static int itype = 0;
module_param(itype, int, 0000);
static bool btype = false;
module_param(btype, bool, 0600);
static int arraytype[5];
static unsigned int arraysize;
module_param_array(arraytype, int, &arraysize, 0444);
static char str[10];
module_param_string(str, str,10, 0400);
//加载内核模块后的入口函数
static int __init module_param_init(void)
{
int i;
printk(KERN_INFO "Module param driver init\n");
printk(KERN_ALERT "itype:%d\n", itype);
kernel_param_lock(THIS_MODULE);
printk(KERN_ALERT "btype:%d\n", btype);
kernel_param_unlock(THIS_MODULE);
for (i = 0; i < arraysize; i++)
{
printk(KERN_ALERT "arraytype[%d]:%d\n", i, arraytype[i]);
}
printk(KERN_ALERT "str:%s\n", str);
return 0;
}
//卸载内核模块后的清理函数
static void __exit module_param_exit(void)
{
printk(KERN_INFO "Module param driver exit\n");
}
module_init(module_param_init);
module_exit(module_param_exit);
MODULE_LICENSE("GPL");
insmod传参
insmod module_param.ko itype=12 btype=Y arraytype=1,2,3,4,5 str=hello
对于数组类型或者字符串类型,它在接受参数时,会检查范围,如果超出,报错退出,模块不会正常加载。

浙公网安备 33010602011771号