//函数源码
#define module_param_call(name,set, get, arg,perm) \
staticconst struct kernel_param_ops__param_ops_##name = \
{.flags = 0, (void *)set, (void *)get }; \
__module_param_call(MODULE_PARAM_PREFIX, \
name, &__param_ops_##name, arg, \
(perm) + sizeof(__check_old_set_param(set))*0, -1,0)
调用module_param_call会填充kernel_param中最重要的就是kernel_param_ops结构体,此结构体会被填充,此结构体包含了set函数指针和get函数指针重要的函数指针。
struct kernel_param {
const char *name;
const struct kernel_param_ops *ops;
u16 perm;
s16 level;
union {
void *arg;
const struct kparam_string *str;
const struct kparam_array *arr;
};
};
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);
};
在__module_param_call函数中,通过__attribute__(__section(“__param”))将数据放入__param字段中,即初始化kernel_param结构体。当通过echo进行输入时,当名字匹配时,则调用set函数。
#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, THIS_MODULE, ops, \
VERIFY_OCTAL_PERMISSIONS(perm), level, flags, { arg } }