반응형
이전 2.6 커널기준 이며, 최신커널에서는 해당내용들에 해당하지 않습니다.
module_param 호출에 대해서...
module_param(var, type, perm)
module_param(irq, int, 0);
이와 같이 호출한다. 호출하는곳을 따라가면...
#define module_param(name, type, perm) \
module_param_named(name, name, type, perm)
#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_call(name, set, get, arg, perm) \
__module_param_call(MODULE_PARAM_PREFIX, name, set, get, arg, perm)
#define __module_param_call(prefix, name, set, get, arg, perm) \
static char __param_str_##name[] = prefix #name; \
static struct kernel_param const __param_##name \
__attribute_used__ \
__attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
= { __param_str_##name, perm, set, get, arg }
딱보면.. 알겠지만.. 일단. \param\str##name[]
에 변수이름을 저장 하며, kernel\param
이라는 구조체를 선언한다.
struct kernel_param {
const char *name;
unsigned int perm;
param_set_fn set;
param_get_fn get;
void *arg;
};
그리고... 아래 \attribute\
부분 보면... 추측이지만.. \param
이라는 섹션을 선언하고... 그곳에.. kernel\param
의 구조체를 넣는것 같다. 그리고.. 그 고제체의 멤버를 { \param\str##name, perm, set, get, arg }
순서대로 넣는것 같음;;
module_param_call(name, param_set_##type, param_get_##type, &value, perm); \
위에 보면... 각 파라미터 type별로 param\set\fn/param\get\fn
로 연결시키는 함수가 틀린데요.. 그것은 아래 선언되어있더군요..
// kernel/params.c
#define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \
int param_set_##name(const char *val, struct kernel_param *kp) \
{ \
char *endp; \
tmptype l; \
\
if (!val) return -EINVAL; \
l = strtolfn(val, &endp, 0); \
if (endp == val || ((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(byte, unsigned char, "%c", unsigned long, simple_strtoul);
STANDARD_PARAM_DEF(short, short, "%hi", long, simple_strtol);
STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, simple_strtoul);
STANDARD_PARAM_DEF(int, int, "%i", long, simple_strtol);
STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, simple_strtoul);
STANDARD_PARAM_DEF(long, long, "%li", long, simple_strtol);
STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, simple_strtoul);
다음..
MODULE_PARM_DESC(irq, "cs89x0 IRQ number");
#define MODULE_PARM_DESC(_parm, desc) \
__MODULE_INFO(parm, _parm, #_parm ":" desc)
#define __MODULE_INFO(tag, name, info) \
static const char __module_cat(name,__LINE__)[] \
__attribute_used__ \
__attribute__((section(".modinfo"),unused)) = __stringify(tag) "=" info
irq = irq_parm : cs89x0 IRQ number
#define ___module_cat(a,b) __mod_ ## a ## b
#define __module_cat(a,b) ___module_cat(a,b)
#define __stringify_1(x) #x
#define __stringify(x) __stringify_1(x)
반응형