1. 如一段模块的代码:hellomod.c(点击)
|
1.1 module_init (lkp_init) 这一段宏展开 :
#define module_init(x) __initcall(x);
#define __initcall(fn) device_initcall(fn)
#define device_initcall(fn) __define_initcall("6",fn,6)
#define __define_initcall(level,fn,id) \
static initcall_t __initcall_##fn##id __used \
__attribute__((__section__(".initcall" level ".init"))) = fn
所以这段宏是:
static initcall_t __initcall_##fn##6 __used __attribute__((__section__(".initcall" “6” ".init"))) = lkp_init
其中 initcall_t 是函数指针原型: typedef int (*initcall_t)(void);
__initcall_##fn##id 就是函数指针的名称,它其实是一个变量名称
__attribute__((__section__(".initcall" level ".init"))) 则表示把对象放在一个这个由括号中的名称所指代的section中。
所以这一段宏的意思是 申请一个变量名为 __initcall_lkp_init6 类型为 typedef int (*initcall_t)(void) 的函数指针,并赋值为 lkp_init。
1.2 module_exit (lkp_exit) 这一段宏展开 :
#define __exitcall(fn) \
static exitcall_t __exitcall_##fn __exit_call = fn
和上一个宏一样,定义一个函数变量并赋值。
1.3 MODULE_LICENSE ("GPL") 这一段宏展开:
#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
#define __module_cat(a,b) ___module_cat(a,b)
#define __stringify_1(x) #x
#define __stringify(x) __stringify_1(x)
static const char __module_cat(name,__LINE__)[] \
__attribute_used__ \
__attribute__((section(".modinfo"),unused)) = __stringify(tag) "=" info
展开后形式如下:
static const char
__mod_license24[] __attribute__ ((__used__))
__attribute__((section(".modinfo"),unused)) = "license" "=" "GPL";
(static const char str[] = "license" "=" "GPL"; 上面的型如这个,定义一个字符数组然后给字符数组赋值)
**** 另外注意上边:
#define ___module_cat(a,b) __mod_ ## a ## b
这一句中的 ## 的用法,(可以自己尝试着是一下)!!!
1.4 module_param(name, type, perm) 解析