网络模块初始化

初始化相关的文件

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

网络模块初始化,布布扣,bubuko.com

时间: 2024-08-22 20:00:08

网络模块初始化的相关文章

nginx笔记资料

通配 hash 表 ngx_hash_init 实现注释:http://blog.csdn.net/gsnumen/article/details/7817396 ngx_hash_init之后的结构制图:http://blog.csdn.net/livelylittlefish/article/details/6636229 ngx_hash_wildcard_init 代码详解和 制图:http://www.cnblogs.com/chengxuyuancc/p/3782808.html v

Libgdx: android单机斗地主支持局域网wifi联网的网络模块核心代码

这个作品是我最近写的,结合我的毕业设计的通信模块和之前的单机版斗地主.我已经上架到豌豆荚了,贴了点广告,看看能不能赚点茶钱.可是一点也不乐观.因此我想分享给大家源码.只要不用于商业. 下面先贴网络模块的核心代码,第一次写这种逻辑用的udp, 经验不够,没有写的那么好看. 这里是我上架的apk,大家下载来试试也无妨: 地址 http://www.wandoujia.com/apps/com.hj.joker package com.hj.net; import java.io.ByteArrayI

网络模块(客户端的连接动作)

一个客户端连接网络模块工作(一个连接的过程) 监听线程收到一个连接后像轮询线程的连接队列中push一个conn_queue_item,然后向soketpair中写入一个字节 此时子线程就是自动调用设置的事件,然后从连接队列中pop一个socket 然后创建一个机遇socket的bufferevent 在createChannel中回调 void TCPServer::on_connect(int channel_id) { packet pkt; pkt.size = (int)link_sta

Java的成员变量初始化

对于方法里面的成员变量,Java要求程序员强制提供一个初始化的值.比如下面这个方法就会出错: public class Breakyizhan{ public void Z(){ int z; z++; } public static void main(String[] args) { Breakyizhan B = new Breakyizhan(); B.Z(); } } /* (www.breakyizhan.com) 输出结果是: 编译会出错,方法变量没有初始化 */ 而对于类的数据,

快学Scala 第二十一课 (初始化trait的抽象字段)

初始化trait的抽象字段: trait Logged { println("Logged constructor") def log(msg: String){ println("Logged")} } trait FileLogger extends Logged { var filename: String override def log(msg: String) { println("filename:" + filename) } }

main.c 流程-buffer初始化

void buffer_init(long buffer_end)函数的理解: *   0         0x100000          0x400000                    0x10 00000(16M) *    ---------------------------------------------------------- *   |   kernel  | memery buffer   |   main memory              |      

AS3 Vecter初始化

var vec : Vecter.<Point> = new <Point>[     new Point(1,1),     new Point(1,2) ]; 类似于 Array的初始化的方法. var arr : Array = [1,2]; 当然Vecter的常规初始化: var vec : Vecter.<Point> = new Vecter.<Point>();//这样的话要赋值的话需要使用push等函数. 注意要: ① new <Poi

对象初始化

对象初始化过程 第一步:在创建之前,检查是否加载(检查硬盘上的class文件是否加载到内存中,如果没有加载,就先加载父类的文件) 在加载父类的文件,在加载本类的文件中java使用的加载的策略:懒惰式加载(按需加载)用到的时候,只加载一次. 第二步:分配对象的空间.递归分配所有父类和子类的属性空间,属性会自动初始化为"0"的值 第三步:给属性赋值 第四步:调用父类的构造方法(默认调用父类的无参构造方法) 第五步:调用本类的构造方法

s5pv210——初始化SDRAM

1:SDRAM基础: 通过s3c2440的内存原理以及时序来理解s5pv210 SDRAM原理.时序. 首先看一下核心板内存如何连接的 可以看一下两个内存芯片接的地址总线均为Xm1_ADDR[13:0],数据总线Xm1_DATA[15:0].Xm1_DATA[31:16],两个内存芯片是并联的,当地址总线Xm1_ADDR[13:0]寻址时, 可以同时在两个内存芯片上各获取16位数据来组成一个32位数据,并由32位数据总线输出. 在看下面这幅图:下图为每个内存芯片内部框图:Block Diagra