定义一个内核参数比较简单
module_param(参数变量名字,类型,访问权限)
MODULE_PARM_DESC(参数变量名字,“参数说明描述”)
如果需要限制或者检查用户输入的参数的值,比如说限制输入的整型数是 256~512的某个范围等等,输入的一定是某个特定字符串等。那么可以用这个宏。这个支持你传进去一个参数处理的回调函数。
module_param_call 2.6.35 以下
module_param_cb 2.6.38
这里我只针对module_param_cb 做一下说明,module_param_call 用法类似,看内核中的定义:
/** * module_param_cb - general callback for a module/cmdline parameter * @name: a valid C identifier which is the parameter name. * @ops: the set & get operations for this parameter. * @perm: visibility in sysfs. * * The ops can have NULL set or get functions. */ #define module_param_cb(name, ops, arg, perm) \ __module_param_call(MODULE_PARAM_PREFIX, \ name, ops, arg, __same_type((arg), bool *), perm)
1、name是你要定义的变量的名字
2、ops中指定你要用于set和get这个变量value的方法
3、arg是你在你的code中默认初始化的这个变量名
4、perm是系统读写等权限的设置
看一个实例你就全明白了static int set_enabled(const char *val, const struct kernel_param *kp) { int rv = param_set_bool(val, kp); if (rv) return rv; if (otgwl_xceiv) otgwl_handle_event(otgwl_xceiv->last_event); return 0; } static struct kernel_param_ops enabled_param_ops = { .set = set_enabled, .get = param_get_bool, }; module_param_cb(enabled, &enabled_param_ops, &enabled, 0644); MODULE_PARM_DESC(enabled, "enable wakelock when VBUS present");我也懒得自己去写code 了,这是内核中的code,也许更有说服力,这个code的路径,感兴趣可以自己去看看:kernel/drivers/usb/otg/otg-wakelock.c
这样一来,这段code会在开发板的sys/module/otg_wakelock/parameters/目录下创建一个名字叫enable的文件,你可以通过这个文件set和get变量enable的数据
read value:cat enable
write value:echo 1 > enable
当你read value的时候,上面ops中定义的方法param_get_bool会被调用,这是内核已经实现的方法,直接get bool,这里我们希望enable是一个bool类型,如果是int类型那么就是get int方法了
同样的,当你write value时,set_enabled这个自己实现的方法会被调用,这里只是进行了简单的检查
其实有些时候你完全可以没有必要这么麻烦,为什么这么说呢??
我们就一点点来看一下,其实内核中module_param可以实现我们上面说的所有这一些功能,这个方法不光可以创建一个指定类型的变量的文件,同时还提供了系统默认的get和set的方法,没有必要我们自己去实现
看看module_param的定义:
/** * module_param - typesafe helper for a module/cmdline parameter * @value: the variable to alter, and exposed parameter name. * @type: the type of the parameter * @perm: visibility in sysfs. * * @value becomes the module parameter, or (prefixed by KBUILD_MODNAME and a * ".") the kernel commandline parameter. Note that - is changed to _, so * the user can use "foo-bar=1" even for variable "foo_bar". * * @perm is 0 if the the variable is not to appear in sysfs, or 0444 * for world-readable, 0644 for root-writable, etc. Note that if it * is writable, you may need to use kparam_block_sysfs_write() around * accesses (esp. charp, which can be kfreed when it changes). * * The @type is simply pasted to refer to a param_ops_##type and a * param_check_##type: for convenience many standard types are provided but * you can create your own by defining those variables. * * Standard types are: * byte, short, ushort, int, uint, long, ulong * charp: a character pointer * bool: a bool, values 0/1, y/n, Y/N. * invbool: the above, only sense-reversed (N = true). */ #define module_param(name, type, perm) \ module_param_named(name, name, type, perm)他调用了module_param_named这个方法
/** * 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)
这个方法的实现是最关键的地方,我们仔细看一下他都做了些什么事情,这里为了方便分析,假定我们的变量type类型是int
1、调用param_check_##type方法,##用于连接两个字符,我在我的C语言每天一小步专栏中说到这个问题,大家可以参考:http://blog.csdn.net/xinyuwuxian/article/details/9033627
这里也就是执行param_check_int,检查变量是不是int 类型2、调用module_param_cb,这里大家应该熟悉了,上面我们已经说的很清楚这个方法了,这不过这里的ops是系统的ops,针对int类型就是param_ops_int
3、最后调用__MODULE_PARM_TYPE方法指定我们的type也就是int,#的用法在我上面提到的专栏文章中也已经说到
这样一来,可以很清楚的理解了,不过需要注意的是module_param_cb这个方法有时还是不可或缺的,就像上面我们不只是要进行参数检查,我们还想加入我们自己的功能,所以这时我们需要自己实现我们的set或者get方法,这个时候module_param_cb就是谁也替代不了的了,这就是天生我材必有用,O(∩_∩)O~
就到这了,O(∩_∩)O~