该宏定义在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. 使用JMETER进行REST API测试(分步指南)

    我确定你在这里是因为你需要加载测试Json Rest API.这并不奇怪,因为Rest API现在越来越受欢迎. 这本指南的目的:帮助您进行负载测试一个Json的 REST API 通过一个具体的例子 ...

  2. tensorflow:实战Google深度学习框架第四章01损失函数

    深度学习:两个重要特性:多层和非线性 线性模型:任意线性模型的组合都是线性模型,只通过线性变换任意层的全连接神经网络与单层神经网络没有区别. 激活函数:能够实现去线性化(神经元的输出通过一个非线性函数 ...

  3. 2017"百度之星"程序设计大赛 - 初赛(A)今夕何夕

    Problem Description 今天是2017年8月6日,农历闰六月十五. 小度独自凭栏,望着一轮圆月,发出了“今夕何夕,见此良人”的寂寞感慨. 为了排遣郁结,它决定思考一个数学问题:接下来最 ...

  4. 错误之Illegal mix of collations for operation 'like'

    内容来自博客:https://www.cnblogs.com/install/p/4417527.html MySQL Illegal mix of collations for operation ...

  5. Crusher Django 学习笔记2 基本url配置

    http://crusher-milling.blogspot.com/2013/09/crusher-django-tutorial2-conf-basic-url.html 顺便学习一下FQ Cr ...

  6. 上白泽慧音——tarjian

    题目描述 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点.人间 ...

  7. 理解C#系列 / 前言

    前言 索引 写什么? 为什么写? 怎么写? 写什么? 写和C#编程相关的知识. 写知识的定义,附加对知识的理解. 写知识的作用,使用的场景,使用的条件. 写知识的本质,技术的结构,工作的原理. 写知识 ...

  8. CString的GetBuffer和ReleaseBuffer

    GetBuffer()主要作用是将字符串的缓冲区长度锁定,releaseBuffer则是解除锁定,使得CString对象在以后的代码中继续可以实现长度自适应增长的功能. CString ::GetBu ...

  9. 两小时学Thinkphp3.1(多数来自thinkphp3.1快速入门)

    调试模式 define('APP_DEBUG',TRUE); 定义自动验证 protected $_validate = array( array('title','require','标题必须'), ...

  10. 使用 Azure 创建存储和检索文件

    本指南将以循序渐进的方式帮助您使用 Azure 将文件存储到云中.我们将逐一介绍如何创建存储账户.创建容器.上传文件.检索文件和删除文件.在本教程中完成的所有操作均符合 1 元试用条件. 本指南将以循 ...