网络模块初始化

初始化相关的文件

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型号的网络设备驱动的初始化函数

posted @ 2017-04-30 18:38  yfceshi  阅读(303)  评论(0编辑  收藏  举报