该宏定义在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));
}

  

最新文章

  1. 【.net+jquery】绘制自定义表单(含源码)
  2. jsonp 跨域 能返回数据但 无法返回成功问题
  3. iOS开发之 Xcode 一个工程 Project 添加多个 target
  4. 【Ubuntu12.04】安装搜狗输入法
  5. 【转】蓝牙4.0BLE cc2540 usb-dongle的 SmartRF Packet Sniffer 抓取数据方法--不错
  6. rpm与dpkg yum与apt-get详解
  7. RabbitMQ4--发后即忘和RPC
  8. LAMP平台部署(转)
  9. thinkphp5.0 分页中伪静态的处理
  10. 2018-2019-1 20189210 《LInux内核原理与分析》第四周作业
  11. 没有可用软件包 libgdiplus 解决方法
  12. java Graphics2D drawString()内容换行问题
  13. elasticsearch中 refresh 和flush区别(转)
  14. SpringCloud与Consul集成实现负载均衡
  15. com.netflix.zuul.exception.ZuulException: Forwarding error
  16. 第7月第27天 c++11 boost
  17. python数据类型内部结构解剖
  18. 【转】如何在ASP.NET 2.0中定制Expression Builders
  19. Jenkins+Ant+Jmeter接口自动化集成测试实例
  20. OpenCV---图像金字塔原理

热门文章

  1. BZOJ1053(数学结论进行剪枝搜索)
  2. [已读]javascript语言精粹
  3. Linux--NiaoGe-Service-07网络安全与主机基本防护
  4. python里面的list、tuple和dict的区别
  5. Connection conn = DriverManager.getConnection(&quot;jdbc:odbc:bbs&quot;);
  6. Spring Cloud Gateway VS Zuul 比较,怎么选择?
  7. CF1061B Views Matter
  8. html的meta总结
  9. WIN32项目中MFC程序窗口居中
  10. Gitlab User Guide