c语言修改内核参数,内核参数module_param的有关操作

本文介绍了如何使用C语言在内核中定义和管理参数,特别是module_param和module_param_cb宏的用法。通过示例展示了如何自定义设置和获取参数值的回调函数,以及如何在sysfs下创建可读写的参数文件。同时讨论了何时需要自定义set和get方法,以及module_param函数的内部工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内核参数module_param的有关操作

定义一个内核参数比较简单

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, &param_ops_##type, &value, perm); \

__MODULE_PARM_TYPE(name, #type)

这个方法的实现是最关键的地方,我们仔细看一下他都做了些什么事情,这里为了方便分析,假定我们的变量type类型是int

1、调用param_check_##type方法,##用于连接两个字符,我在我的C语言每天一小步专栏中说到这个问题,大家可以参考:http://www.voidcn.com/article/p-avdhmpdn-wz.html 这里也就是执行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~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值