module_param
该宏定义在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的更多相关文章
- [Linux编程] module_param()函数学习笔记
在读TCP cubic源码中,遇到了module_param(),网上查到的资料如下: 在用户态下编程可以通过main()来传递命令行参数,而编写一个内核模块则可通过module_param()来传递 ...
- linux下的module_param()解释【转】
转自:http://blog.csdn.net/wavemcu/article/details/7762133 版权声明:本文为博主原创文章,未经博主允许不得转载. ***************** ...
- insmod module_param 模块参数
模块参数 引导模块时,可以向它传递参数.要使用模块参数加载模块,这样写: insmod module.ko [param1=value param2=value ...] 为了使用这些参数的值,要在模 ...
- 关于module_param()宏
在用户态下编程可以通过main()的来传递命令行参数,而编写一个内核模块则通过module_param () module_param宏是Linux 2.6内核中新增的,该宏被定义在include/l ...
- linux驱动: 如何向模块传递参数, module_param和module_param_array
如何向模块传递参数,Linux kernel 提供了一个简单的框架. 1. module_param(name, type, perm); name 既是用户看到的参数名,又是模块内接受参数的 ...
- module_param()函数
1.定义模块参数的方法: module_param(name, type, perm); 其中,name:表示参数的名字; type:表示参数的类型; perm:表示参数的访问权限; ...
- linux驱动开发第二步 驱动模块传参(module_param函数使用)
在驱动的模块中声明一下你要传递的参数名称,类型和权限 module_param(变量的名称,类型,权限); 先上例子 #include <linux/init.h> #include &l ...
- module_param和module_param_array用法
如何向模块传递参数? Linux kernel 提供了一个简单的框架.利用module_param和module_param_arra来实现. 1. module_param(name, type, ...
- module_param 用于动态开启/关闭 驱动打印信息
1.定义模块参数的方法: module_param(name, type, perm); 其中,name:表示参数的名字; type:表示参数的类型; perm:表示参数的访问权限 ...
随机推荐
- bzoj3583 杰杰的女性朋友 || bzoj4362 Graph
http://210.33.19.103/problem/2174 很显然是矩阵快速幂的题,设有in和ou矩阵,设in矩阵的转置为in' 显然可以直接暴力求出任意两点间走一步路径条数,然后求其d次幂, ...
- python入门之实例-用户登录、注册
用户密码存储文件db(其中用户和密码之间用$符合隔开): admin$123456 root$sdfk9f24 chy$654321 代码如下: def login(username,password ...
- Mex(线段树的巧妙应用)
题目要求求某段区间第一个没有出现的数(0,1,2,3....) ,对于所有的区间,我们把这样的数加起来最后得到一个结果. 首先,我们要求出这样的数,然后还得列举出所有的区间,复杂度太大了. 换种思路, ...
- 解决“程序包管理器控制台”输入命令找不到Nuget包问题
问题: 问题原因: Nuget源的地址上不去 解决办法: 1.将Nuget源更新为可以国内使用的官方Nuget源. 1)打开VS2013:工具-->Nuget程序包管理器-->程序包管理器 ...
- 回顾Quick Sort(Javascript 实现)
Introduction QuickSort的时间复杂度渐近函数虽然不能达到MergeSort般的O(nlgn),但因其良好的时间常量以及平均运行时间而被广泛使用. 下图解释了QuickSort的过程 ...
- AJPFX分享JAVA修饰符详解
1.类的修饰符分为:可访问控制符和非访问控制符两种. 可访问控制符是:公共类修饰符 public 非访问控制符有:抽象类修饰符 abstract :最终类修饰符 final 1 )公共类修饰符 pub ...
- ios自定义日期、时间、城市选择器
选择器,我想大家都不陌生,当需要用户去选择某些范围值内的一个固定值时,我们会采用选择器的方式.选择器可以直观的提示用户选择的值范围.统一信息的填写格式,同时也方便用户快速的进行选择,比如对于性别,正常 ...
- iOS 多尺寸屏幕适配
Point Point可以理解为iOS程序员眼中的大小单位.它是iOS操作系统中的抽象的概念. Rendered Pixels可以理解为UI设计师眼中的大小单位. Physical Pixels 设备 ...
- 诊断 Grid Infrastructure 启动问题 (文档 ID 1623340.1)
适用于: Oracle Database - Enterprise Edition - 版本 11.2.0.1 和更高版本本文档所含信息适用于所有平台 用途 本文提供了诊断 11GR2 和 12C G ...
- (转)MyBatis框架的学习(五)——一对一关联映射和一对多关联映射
http://blog.csdn.net/yerenyuan_pku/article/details/71894172 在实际开发中我们不可能只是对单表进行操作,必然要操作多表,本文就来讲解多表操作中 ...