内核之旅 --- 内核模块学习1---内核模块参数传递
2015-09-12 10:32
465 查看
内核模块的参数传递:
内核模块在加载时是可以添加参数的,但是支持类型有所改变。
首先,内核模块中的变量如果需要使用外界传递的参数需要使用特定的宏
module_param(member,type,perm)
这三个参数分别表示:
member: 变量名
type : 类型名
perm : 入口项的访问许可源码。
只有使用这个宏才能使我们驱动里边的参数接受到外面的值。
内核支持的模块参数类型有下面几种:
bool :布尔值(取ture 或 false ),关联的变量应该是int型。
invbool: 类型反转其值,也就是说,ture 值变成false , 而false 变成 ture.
charp:字符指针值。内核会为用户提供的字符串分配内存,并相应设置指针。
int ,long , short ,uint ,ulong ,ushort 具有不同长度的基本整数值,以U开头就是无符号值。
也可以接受数组,需要使用宏:
module_param_array(name,type,num,perm);
其中name 就是数组名,type 是数组的元素类型,num 是一个整数变量就是数组元素的个数,越界值直接报错。详情参见moduleparam.h .
这个文件在源码包/include/linux/moduleparam.h
我们可以尝试分析一下,追踪一下这个源码:
可以看到这就是数组分配宏的源码,它调用的是
module_param_array_named(name,name,type,nump,perm)
那好,我们再追踪这个宏看看
英语真麻烦。。。。算了还是翻译给大家看看吧。
第一行:重命名数组的参数
@name:一个有效的C表示符作为参数的名字
@array:数组明变量
@type:类型
@nump:数组长度
@perm:文件系统的能见度(俗称权限)
这个操作生成一个不同的名字而不是真正的名字,他要我们查看另一个宏。
就是检查这个类型是否有效,“##” 是C中的宏替换运算符,他接受一个名字,和长度。安全检查。
module_param_cd(name,¶m_ops_##type,&value,perm)
这个宏调用的是__module_param_call
回到上边这个宏,我们看到再次确定了变量名与类型的匹配
然后这个数组就算是定义成功,当使用时,内核会让加载器给它分配相应内存。其实这些宏的工作仅仅是检查参数,保存参数。
内核模块在加载时是可以添加参数的,但是支持类型有所改变。
首先,内核模块中的变量如果需要使用外界传递的参数需要使用特定的宏
module_param(member,type,perm)
这三个参数分别表示:
member: 变量名
type : 类型名
perm : 入口项的访问许可源码。
<span style="font-size:18px;">static char *whom = "world"; static int howmany = 1; module_param(howmany,int,S_IRUGO); module_param(whom,charp,S_IRUGO);</span>
只有使用这个宏才能使我们驱动里边的参数接受到外面的值。
内核支持的模块参数类型有下面几种:
bool :布尔值(取ture 或 false ),关联的变量应该是int型。
invbool: 类型反转其值,也就是说,ture 值变成false , 而false 变成 ture.
charp:字符指针值。内核会为用户提供的字符串分配内存,并相应设置指针。
int ,long , short ,uint ,ulong ,ushort 具有不同长度的基本整数值,以U开头就是无符号值。
也可以接受数组,需要使用宏:
module_param_array(name,type,num,perm);
其中name 就是数组名,type 是数组的元素类型,num 是一个整数变量就是数组元素的个数,越界值直接报错。详情参见moduleparam.h .
这个文件在源码包/include/linux/moduleparam.h
我们可以尝试分析一下,追踪一下这个源码:
/** * module_param_array - a parameter which is an array of some type * @name: the name of the array variable * @type: the type, as per module_param() * @nump: optional pointer filled in with the number written * @perm: visibility in sysfs * * Input and output are as comma-separated values. Commas inside values * don't work properly (eg. an array of charp). * * ARRAY_SIZE(@name) is used to determine the number of elements in the * array, so the definition must be visible. */ #define module_param_array(name, type, nump, perm) \ module_param_array_named(name, name, type, nump, perm)
可以看到这就是数组分配宏的源码,它调用的是
module_param_array_named(name,name,type,nump,perm)
那好,我们再追踪这个宏看看
/** * module_param_array_named - renamed parameter which is an array of some type * @name: a valid C identifier which is the parameter name * @array: the name of the array variable * @type: the type, as per module_param() * @nump: optional pointer filled in with the number written * @perm: visibility in sysfs * * This exposes a different name than the actual variable name. See * module_param_named() for why this might be necessary. */ #define module_param_array_named(name, array, type, nump, perm) \ param_check_##type(name, &(array)[0]); \ static const struct kparam_array __param_arr_##name \ = { .max = ARRAY_SIZE(array), .num = nump, \ .ops = ¶m_ops_##type, \ .elemsize = sizeof(array[0]), .elem = array }; \ __module_param_call(MODULE_PARAM_PREFIX, name, \ ¶m_array_ops, \ .arr = &__param_arr_##name, \ perm, -1, 0); \ __MODULE_PARM_TYPE(name, "array of " #type)
英语真麻烦。。。。算了还是翻译给大家看看吧。
第一行:重命名数组的参数
@name:一个有效的C表示符作为参数的名字
@array:数组明变量
@type:类型
@nump:数组长度
@perm:文件系统的能见度(俗称权限)
这个操作生成一个不同的名字而不是真正的名字,他要我们查看另一个宏。
/** * module_param_named - typesafe helper for a renamed module/cmdline parameter * @name: a valid C identifier which is the parameter name. * @value: the actual lvalue to alter. * @type: the type of the parameter * @perm: visibility in sysfs. * * Usually it's a good idea to have variable names and user-exposed names the * same, but that's harder if the variable must be non-static or is inside a * structure. This allows exposure under a different name. */ #define module_param_named(name, value, type, perm) \ param_check_##type(name, &(value)); \ module_param_cb(name, ¶m_ops_##type, &value, perm); \ __MODULE_PARM_TYPE(name, #type)param_check_##type(name,&(value));
就是检查这个类型是否有效,“##” 是C中的宏替换运算符,他接受一个名字,和长度。安全检查。
module_param_cd(name,¶m_ops_##type,&value,perm)
这个宏调用的是__module_param_call
/* This is the fundamental function for registering boot/module parameters. */ #define __module_param_call(prefix, name, ops, arg, perm, level, flags) \ /* Default value instead of permissions? */ \ static const char __param_str_##name[] = prefix #name; \ static struct kernel_param __moduleparam_const __param_##name \ __used \ __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ = { __param_str_##name, ops, VERIFY_OCTAL_PERMISSIONS(perm), \ level, flags, { arg } }这个函数在模块中注册一个变量。
回到上边这个宏,我们看到再次确定了变量名与类型的匹配
__MODULE_PARM_TYPE(name, #type)
然后这个数组就算是定义成功,当使用时,内核会让加载器给它分配相应内存。其实这些宏的工作仅仅是检查参数,保存参数。
相关文章推荐
- 内核之旅 --- 内核模块学习1---内核模块参数传递
- 深入解析字符串的比较方法:“==”操作符;String.Equals方法;String.Compare方法;String.CompareOrdinal方法。
- [Leetcode]Closest Binary Search Tree Value
- 汽车租赁管理系统及所涉及面向对象的一般步骤
- 数据挖掘(7):分类算法评价
- 苹果的玫瑰金与小米的粉色版
- hdu acm 1171 Big Event in HDU
- 在一个指定的div中拖拽
- JAVA中的SimpleDateFormat yyyy和YYYY的区别
- 数据挖掘(6):决策树分类算法
- linux下weblogic 12c 之软件安装
- C/C++常用头文件及函数汇总
- python与shell的3种交互方式介绍
- c++ profilers
- 数据挖掘(5):使用mahout做海量数据关联规则挖掘
- Gemfile 详解
- php文件扩展名判断
- angularJS web应用SEO
- 关于美剧的一个网站
- 【视频处理】YUV格式说明