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:表示参数的访问权限 ...
随机推荐
- 最短路之Floyd(多源)HDU 1874
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #def ...
- GYM 101889B(找规律)
乍一看很唬人,草稿纸上多写几个发现规律:两个元音算一层,像剥洋葱一样,外面的其实都动不了,能变顺序的只有最里层的辅音. inline bool ok(char ch) { return ch == ' ...
- 转 用好HugePage,告别Linux性能故障
超过32G 的数据库,可以是使用如下方法配置. ######### Slow Performance with High CPU Usage on 64-bit Linux with Large SG ...
- 【转】Effective C#观后感之提高Unity中C#代码质量的21条准则
转自:http://blog.csdn.net/swj524152416/article/details/75418162 我们知道,在C++领域,作为进阶阅读材料,必看的书是<Effectiv ...
- C#oracle备份和还原
最近公司的oracle备份工具不好使了,原来是公司的人用VB写的,由于我是主攻C#的,所以想着自己来写一个C#版本的oracle备份和还原工具. 一开始,我按照原来的设计思路来进行编写,想在pluss ...
- Java方式配置Spring
概述 本文主要讲的是如何使用Java Bean来配置Spring,而不是用xml来配置Spring. 本文主要是代码,需要注意的都在注释里面. 代码打包下载地址(注:项目使用Maven构建) Java ...
- option标签selected="selected"属性失效的问题
要在select标签上面加上autocomplete="off"关闭自动完成,不然浏览器每次刷新后将自动选择上一次关闭时的option,这样默认属性selected="s ...
- _CrtDumpMemoryLeaks()的作用 检测内存泄漏
_CrtDumpMemoryLeaks()的作用 2007-03-22 10:11 CrtDumpMemoryLeaks()就是显示当前的内存泄漏. 注意是“当前”, 也就是说当它执行 ...
- iOS之创建CocoaPods公有库教程
简介 在开发过程中,经常会使用到第三框架,我们通过一个pod install命令,很方便的就将第三方框架加到我们自己的项目中. 如果我们也想将自己写的组件或库开源出去,让别人也可以通过pod inst ...
- apache安装报错
libtool: install: error: cannot install `libaprutil-1.la' to a directory not ending /some_directory ...