驱动初始化/退出
参考1. initcall和module_init - 知乎 (zhihu.com)
MODULE宏
MODULES宏用于区分,驱动内置与模块加载。由Makefile中动态传入,
KBUILD_AFLAGS_MODULE := -DMODULE
KBUILD_CFLAGS_MODULE := -DMODULE
头文件
# V4.19.232
# kernel/include/linux/module.h
...
#ifndef MODULE
#define module_init(x) __initcall(x);
#define module_exit(x) __exitcall(x);
#else /* MODULE */
#define early_initcall(fn) module_init(fn)
...
/* Each module must use one module_init(). */
#define module_init(initfn) \
static inline initcall_t __maybe_unused __inittest(void) \
{ return initfn; } \
int init_module(void) __copy(initfn) __attribute__((alias(#initfn)));
/* This is only required if you want to be unloadable. */
#define module_exit(exitfn) \
static inline exitcall_t __maybe_unused __exittest(void) \
{ return exitfn; } \
void cleanup_module(void) __copy(exitfn) __attribute__((alias(#exitfn)));
#endif
可知MODULE定义时,有:
-
定义了一个静态内联函数
__inittest
,该函数无入参并返回int类型,该函数直接调用initfn;initcall_t
,函数指针,类型:无入参而返回int的函数指针;__maybe_unused
,规避函数未调用警告;
-
定义了一个函数init_module,该函数等效于
initfn
(复制属性并创建别名)。__copy(initfn)
:从initfn复制函数属性,从gcc-9开始支持。__attribute__((alias(#initfn)))
:为init_module创建别名,指向原来的initfn。