初始化相关的文件
include/linux/init.h 初始化相关的宏定义
include/asm-generic/vmlinux.lds.h 编译链接相关的宏定义
init/main.c 启动时的高级初始化
net/core/dev.c 网络设备注册、输入和输出等接口
drivers/net/e100.c e100驱动程序
初始化函数调用关系
对模块的初始化,一般通过module_init()宏来登记初始化函数,设备驱动程序可以静态编译到内核,也可以作为一个内核模块动态加载和卸载。这两种方法初始化过程是不一样的。而module_init()宏可以自动根据编译条件来选择初始化的方法。
静态编译条件下的module_init()宏定义
includle/linux/init.h
-
typedef int (*initcall_t)(void);
-
#define __define_initcall(level,fn,id) \
-
static initcall_t __initcall_##fn##id __used \
-
__attribute__((__section__(".initcall" level ".init"))) = fn
-
#define device_initcall(fn) __define_initcall("6",fn,6)
-
#define __initcall(fn) device_initcall(fn)
-
#define module_init(x) __initcall(x);
include/asm-generic/vmlinux.lds.h
-
#define INITCALLS \
-
*(.initcallearly.init) \
-
VMLINUX_SYMBOL(__early_initcall_end) = .; \
-
*(.initcall0.init) \
-
*(.initcall0s.init) \
-
*(.initcall1.init) \
-
*(.initcall1s.init) \
-
*(.initcall2.init) \
-
*(.initcall2s.init) \
-
*(.initcall3.init) \
-
*(.initcall3s.init) \
-
*(.initcall4.init) \
-
*(.initcall4s.init) \
-
*(.initcall5.init) \
-
*(.initcall5s.init) \
-
*(.initcallrootfs.init) \
-
*(.initcall6.init) \
-
*(.initcall6s.init) \
-
*(.initcall7.init) \
-
*(.initcall7s.init)
-
-
#define INIT_CALLS \
-
VMLINUX_SYMBOL(__initcall_start) = .; \
-
INITCALLS \
-
VMLINUX_SYMBOL(__initcall_end) = .;
init/main.c
-
static
void __
init do_initcalls(void)
-
{
-
initcall_t *call;
-
-
for (call = __early_initcall_end; call < __initcall_end; call++)
-
do_one_initcall(*call);
-
-
/* Make sure there is no pending stuff from the initcall sequence */
-
flush_scheduled_work();
-
}
模块加载函数的module_init()宏定义
-
#define module_init(initfn) \
-
static inline initcall_t __inittest(void) \
-
{ return initfn; } \
-
int init_module(void) __attribute__((alias(#initfn)));
module_init(x)的实现在模块中定义一个别名为init_module的x函数。作为能动态加载的模块,如需初始化,Linux规定初始化接口必须为init_module,模块被加载时,init_module()系统调用会根据x得到初始化函数的地址,并调用。
修饰函数的宏
宏 使用宏的函数说明
__init 启动时初始化函数,在启动阶段执行,通常只执行一次。后期不再需要,这种函数在初始 化完成后被从内存中清除
__exit 和__init匹配,相关内核组件卸载时调用,常用于module_exit所修饰的函数
core_initcall
postcore_initcall
arch_initcall
subsys_initcall
fs_initcall 用于标记启动时需要执行的初始化函数
device_initcall
late_initcall
__initcall device_initcall的别名
__exitcall 标识退出函数,相关内核组件卸载时调用。通常仅用于标记module_exit函数
初始化数据结构的宏
宏 使用宏的数据说明
__initdata 仅在启动时用于已初始化的数据结构
__exitdata 仅被由__exitcall修饰的函数使用的数据结构
网络设备处理层初始化
文件 初始化函数及宏 说明
net/socket.c core_initcall(sock_init) 套接口层的初始化函数
net/core/sock.c subsys_initcall(proto_init) 传输层的初始化函数
net/ipv4/af_inet.c fs_initcall(inet_init) Internet协议族的初始化函数
net/core/dev.c subsys_initcall(net_dev_init) 设备处理层的初始化函数
drivers/net/e100.c module_init(e100_init_module) e100型号的网络设备驱动的初始化函数