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) < 0 || (perm) > 0777 || ((perm) & 2))    
    + 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=1;
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) < 0 || (perm) > 0777 || ((perm) & 2))    
    + 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) < 0 || (perm) > 0777 || ((perm) & 2)) + 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));	
}

  

原文地址:https://www.cnblogs.com/yangjiguang/p/8290518.html