该宏定义在include/linux/moduleparam.h中

#define ___module_cat(a,b) __mod_ ## a ## b
#define __module_cat(a,b) ___module_cat(a,b)
#define __MODULE_INFO(tag, name, info) \
static const char __module_cat(name,__LINE__)[] \
__used \
__attribute__((section(".modinfo"),unused)) = __stringify(tag) "=" info #define __MODULE_PARM_TYPE(name, _type) \
__MODULE_INFO(parmtype, name##type, #name ":" _type)
/* This is the fundamental function for registering boot/module
parameters. perm sets the visibility in sysfs: 000 means it's
not there, read bits mean it's readable, write bits mean it's
writable. */
#define __module_param_call(prefix, name, set, get, arg, perm) \
/* Default value instead of permissions? */ \
static int __param_perm_check_##name __attribute__((unused)) = \
BUILD_BUG_ON_ZERO((perm) < || (perm) > || ((perm) & )) \
+ BUILD_BUG_ON_ZERO(sizeof(""prefix) > MAX_PARAM_PREFIX_LEN); \
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, perm, set, get, { arg } } #define module_param_call(name, set, get, arg, perm) \
__module_param_call(MODULE_PARAM_PREFIX, name, set, get, arg, perm) /* Helper functions: type is byte, short, ushort, int, uint, long,
ulong, charp, bool or invbool, or XXX if you define param_get_XXX,
param_set_XXX and param_check_XXX. */
#define module_param_named(name, value, type, perm) \
param_check_##type(name, &(value)); \
module_param_call(name, param_set_##type, param_get_##type, &value, perm); \
__MODULE_PARM_TYPE(name, #type) #define module_param(name, type, perm) \
module_param_named(name, name, type, perm)

下面以驱动模块中的用例展开宏,

static int tiger=;
module_param(tiger,int,S_IRUGO)

1.第一步展开

#define module_param(name, type, perm)                \
module_param_named(name, name, type, perm)

展开结果为

module_param_named(tiger,tiger,int,S_IRUGO)    

2.第二步展开,展开为三项

/* Helper functions: type is byte, short, ushort, int, uint, long,
ulong, charp, bool or invbool, or XXX if you define param_get_XXX,
param_set_XXX and param_check_XXX. */
#define module_param_named(name, value, type, perm) \
param_check_##type(name, &(value)); \
module_param_call(name, param_set_##type, param_get_##type, &value, perm); \
__MODULE_PARM_TYPE(name, #type)

2.1 param_check_##type(name, &(value));

展开结果为,又是一个宏定义

__param_check(tiger, &(tiger), int)
#define __param_check(name, p, type) \
static inline type *__check_##name(void) { return(p); }

上面的宏再展开为一个内联函数,返回某类型的指针

static inline int*__check_tiger(void) { return(&(tiger)); 

2.2 module_param_call(name, param_set_##type, param_get_##type, &value, perm);

这也是一个宏

#define MODULE_PARAM_PREFIX /* empty */
#define module_param_call(name, set, get, arg, perm)                  \
__module_param_call(MODULE_PARAM_PREFIX, name, set, get, arg, perm)

展开为

__module_param_call(MODULE_PARAM_PREFIX,tiger, param_set_int, param_get_int, &tiger, S_IRUGO)
#define __module_param_call(prefix, name, set, get, arg, perm)        \
/* Default value instead of permissions? */ \
static int __param_perm_check_##name __attribute__((unused)) = \
BUILD_BUG_ON_ZERO((perm) < || (perm) > || ((perm) & )) \
+ BUILD_BUG_ON_ZERO(sizeof(""prefix) > MAX_PARAM_PREFIX_LEN); \
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, perm, set, get, { arg } }

上面的宏又展开为3项

2.2.1

static int __param_perm_check_tiger __attribute__((unused)) =    BUILD_BUG_ON_ZERO((perm) <  || (perm) >  || ((perm) & )) + BUILD_BUG_ON_ZERO(sizeof(""prefix) > MAX_PARAM_PREFIX_LEN);

2.2.2

static const char __param_str_tiger[] = "tiger";    

2.2.3

static struct kernel_param  __param_tiger      __used    __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *))))
= { __param_str_tiger, S_IRUGO, param_set_int, param_get_int, {&tiger} }

2.3 __MODULE_PARM_TYPE(name, #type)

#define __MODULE_PARM_TYPE(name, _type)                      \
__MODULE_INFO(parmtype, name##type, #name ":" _type)

该宏展开如下

__MODULE_INFO(parmtype, tigertype, "tiger" ":" "int")
#define ___module_cat(a,b) __mod_ ## a ## b
#define __module_cat(a,b) ___module_cat(a,b)
#define __MODULE_INFO(tag, name, info) \
static const char __module_cat(name,__LINE__)[] __used \
__attribute__((section(".modinfo"),unused)) = __stringify(tag) "=" info

最终展开为

static const char __mod_tigertype__LINE__[] __attribute__((section(".modinfo"),unused)) = "parmtype=tiger:int"

还有一个重要的宏,定义了get/set参数的函数

#define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn)      	\
int param_set_##name(const char *val, struct kernel_param *kp) \
{ \
tmptype l; \
int ret; \
\
if (!val) return -EINVAL; \
ret = strtolfn(val, 0, &l); \
if (ret == -EINVAL || ((type)l != l)) \
return -EINVAL; \
*((type *)kp->arg) = l; \
return 0; \
} \
int param_get_##name(char *buffer, struct kernel_param *kp) \
{ \
return sprintf(buffer, format, *((type *)kp->arg)); \
}

以STANDARD_PARAM_DEF(int, int, "%i", long, strict_strtol);为例展开如下:

int param_set_int(const char *val, struct kernel_param *kp)
{
long l;
int ret; if (!val) return -EINVAL;
ret = strict_strtol(val, 0, &l);
if (ret == -EINVAL || ((long)l != l))
return -EINVAL;
*((long *)kp->arg) = l;
return 0;
}
int param_get_int(char *buffer, struct kernel_param *kp)
{ \
return sprintf(buffer, "%i", *((long *)kp->arg));
}

  

module_param的更多相关文章

  1. [Linux编程] module_param()函数学习笔记

    在读TCP cubic源码中,遇到了module_param(),网上查到的资料如下: 在用户态下编程可以通过main()来传递命令行参数,而编写一个内核模块则可通过module_param()来传递 ...

  2. linux下的module_param()解释【转】

    转自:http://blog.csdn.net/wavemcu/article/details/7762133 版权声明:本文为博主原创文章,未经博主允许不得转载. ***************** ...

  3. insmod module_param 模块参数

    模块参数 引导模块时,可以向它传递参数.要使用模块参数加载模块,这样写: insmod module.ko [param1=value param2=value ...] 为了使用这些参数的值,要在模 ...

  4. 关于module_param()宏

    在用户态下编程可以通过main()的来传递命令行参数,而编写一个内核模块则通过module_param () module_param宏是Linux 2.6内核中新增的,该宏被定义在include/l ...

  5. linux驱动: 如何向模块传递参数, module_param和module_param_array

    如何向模块传递参数,Linux kernel 提供了一个简单的框架.    1.  module_param(name, type, perm); name 既是用户看到的参数名,又是模块内接受参数的 ...

  6. module_param()函数

    1.定义模块参数的方法: module_param(name, type, perm); 其中,name:表示参数的名字;     type:表示参数的类型;     perm:表示参数的访问权限; ...

  7. linux驱动开发第二步 驱动模块传参(module_param函数使用)

    在驱动的模块中声明一下你要传递的参数名称,类型和权限 module_param(变量的名称,类型,权限); 先上例子 #include <linux/init.h> #include &l ...

  8. module_param和module_param_array用法

    如何向模块传递参数? Linux kernel 提供了一个简单的框架.利用module_param和module_param_arra来实现. 1. module_param(name, type, ...

  9. module_param 用于动态开启/关闭 驱动打印信息

    1.定义模块参数的方法: module_param(name, type, perm); 其中,name:表示参数的名字;      type:表示参数的类型;      perm:表示参数的访问权限 ...

随机推荐

  1. C++ Sort类成员的传递

    C++模板中提供了sort方法,一般有两种方法:传递函数,传递一个对象. 第一种方法:函数 bool compare(const string &strLeft, const string & ...

  2. 17115 ooxx numbers 交表

    17115 ooxx numbers 时间限制:1000MS  内存限制:65535K提交次数:0 通过次数:0 题型: 编程题   语言: G++;GCC Description a number ...

  3. ubuntu中wine下安装QQ

    原文:http://jingyan.baidu.com/article/359911f55da27057fe0306d8.html 可以把win改成最新版

  4. HTML5+CSS3新增内容总结!!!!!绝对干货

    说到H5C3会不会觉得东西好多啊,今天就整理了一份总结性的内容: CSS3选择器有哪些?答:属性选择器.伪类选择器.伪元素选择器.CSS3新特性有哪些?答:1.颜色:新增RGBA,HSLA模式 文字阴 ...

  5. IOS命名

    NS开头的名称不要出现. NS系统名称开头. 命名缩写只用于通用专业术语,如URL,不可自创命名缩写,如Ctr.Msg.命名宁可长一些,也不要难于理解. 是否在看别人代码时各种缩写而不知其所以然?简短 ...

  6. cocoapods学习

    1.安装 http://stackoverflow.com/questions/16459028/rvm-install-error-running-requirements-osx-port-ins ...

  7. (十四)maven之启动tomcat

    前言:在网上找了好几种方法启动web项目.比较好用的是:①在Project Facets勾上Dynamic....,但是这个方法会改变项目结构(把WebContent的东西都弄出来了):②使用jett ...

  8. HDOJ1195 双向BFS //单向也可以过 没想清

    #include<cstdio> #include<map> #include<vector> #include<stack> #include< ...

  9. 从汇编看c++中临时对象的析构时机

    http://www.cnblogs.com/chaoguo1234/archive/2013/05/12/3074425.html c++中,临时对象一旦不需要,就会调用析构函数,释放其占有的资源: ...

  10. CAD交互绘制圆形云线批注(网页版)

    js中实现代码说明: 动态拖放时的绘制事件: function DoDynWorldDrawFun(dX,dY,pWorldDraw,pData) { //自定义实体的GUID标识符 var sGui ...