module_init()这个接口应该是驱动开发人员常用的一个接口了,在内核源码里也可以看到无数。
下午详细跟了一下内核代码,顺便分享一下,也算是自己做个记录。
源代码:MTK ALPS 4.4
首先是宏module_init的原始定义:
#define module_init(x) __initcall(x);
定义成了__initcall(),再看__initcall():
#define __initcall(fn) device_initcall(fn)
定义成了device__initcall(),再看device__initcall():
#define device_initcall(fn) __define_initcall("6",fn)
定义成了__define_initcall(“6”,fn),再看__define_initcall(“6”,fn):
#define __define_initcall(level,fn) \
static initcall_t __initcall_##fn __used \
__attribute__((__section__(".initcall" level ".init"))) = fn
可以看到module_init()宏最终把传进来的函数fn组装成了__initcall_fn,并且把函数fn定义到代码段.initcall6.init里面。
找到含有INIT_CALLS字符的文件vmlinux.lds.h:
#define INIT_CALLS_LEVEL(level) \
VMLINUX_SYMBOL(__initcall##level##_start) = .; \
*(.initcall##level##.init) \
*(.initcall##level##s.init) \
#define INIT_CALLS \
VMLINUX_SYMBOL(__initcall_start) = .; \
*(.initcallearly.init) \
INIT_CALLS_LEVEL(0) \
INIT_CALLS_LEVEL(1) \
INIT_CALLS_LEVEL(2)