Linux 网络初始化流程

来源:互联网 发布:低头娶媳妇 知乎 编辑:程序博客网 时间:2024/06/01 10:43

Linux 网络初始化流程

1.       系统初始化

(1)       X86 PC初始化过程

1)  CPU自身初始化

2)  BIOS加电自检POST

完成系统硬件的检测,包括内存检测、系统总线检测等

3)  BIOS加载内核主引导程序

MBR中的主引导程序包括446字节的程序代码和64字节的分区表,最后两个字节为0xAA55

4)  内核主引导程序加载次引导程序

次引导程序负责加载Linux内核映像,并将控制权交给内核

5)  启动内核

1>.Start()汇编例程:进行一些基本的硬件设置

2>Startup_32()汇编例程,设置一个基本的运行环境(堆栈等),并清除BSS,解压内核

3>第二个Startup_32()对页表进行初始化,启用内存分页功能,并为任何可选的浮点单元(FPU)检测CPU的类型,将其存储起来供以后使用

4>init/main.c中的start_kernel函数

内核的初始化过程

(2)       内核初始化

内核初始化由start_kernel开始,至第一个用户进程init结束

1)  start_kernel()

page_address_init()初始化页地址,使用链表将其链接起来

sched_init()初始化进程调度器

init_timers()初始化定时器

softirq_init()初始化tasklet_softirqhi_softirq

time_init()初始化系统时钟

rest_init()

2)  rest_init()

启动内核线程kernel_initkthreadd,运行kthread_create_list全局链表中的kthread

3)  kernel_init

调用do_basic_setup函数初始化设备,完成外设及其驱动程序(直接编译进内核的模块)加载和初始化

static void __init do_basic_setup(void)

{

       cpuset_init_smp();

       usermodehelper_init();

       init_tmpfs();

       driver_init();

       init_irq_proc();

       do_ctors();

       do_initcalls();

}

4)  init_post

运行第一个用户空间进程init

       run_init_process("/sbin/init");

       run_init_process("/etc/init");

       run_init_process("/bin/init");

       run_init_process("/bin/sh");

2.       网络协议栈初始化

位于__initcall_start__initcall_end之间的区域组成了.initcall.init节,其中保存了由xxx_initcall形式的宏标记的函数地址,do_initcall函数可以取得函数地址并执行其指向的函数。

(1)       core_initcall:sock_init

分配一些内存空间,以及创建了一个sock_fs_type的文件系统。

(创建一个套接字缓冲区,最常用的操作是alloc_skb,它在skbuff_head_cache中创建一个struct sk_buff,如果要在skbuff_fclone_cache中创建,可以调用__alloc_skb,通过特定参数进行。)

文件系统:首先是调用register_filesystem(&sock_fs_type);把文件系统类型注册到file_system链表上,然后调用kern_mount(&sock_fs_type);把该文件系统注册到super_blocks上。

(2)       fs_initcall:inet_init

 

(3)       subsys_initcall:net_dev_init

网络子系统的初始化,这一层主要提供一些设备无关的处理流程,也提供一些公用的函数给底层的Device Driver调用。为网络协议提供统一的发送、接收接口。

1)  创建在/proc文件系统下的入口

2)  流量管理初始化

为每个CPU建立网络数据包的接收/发送队列;向系统注册接收网络数据包的上层协议栈的接收处理函数,这些协议处理函数在向量表ptype_base中进行管理;向系统注册网络子系统中接收/发送数据包的两个软件中断处理函数(NET_TX_SOFTIRQNET_RX_SOFTIRQ

3)  设备与事件初始化

遍历网络设备实例列表,将初始化失败的设备从设备链表中移走;

CPU热插拔的事件通知链注册网络子系统的回调函数,一旦CPU热插拔事件发生,该回调函数dev_cpu_callback处理CPU事件

4)  初始化路由与其他初始化过程

独立于协议栈的目的路由CacheDST),由dst_init函数初始化

注册网络子系统

(4)       device_initcall:设备驱动初始化

3.       send 系统调用

内核代码:sys_sendto(fd,buff,len,flags,NULL,0);

应用层待发送的数据放在自己申请的Buff中,而在INET Socket层使用msghdr{}结构组织数据,而在INET Socket层以下都使用sk_buff{}结构组织数据。

struct msghdr {

       void *     msg_name;     /* Socket name                    */

       int           msg_namelen; /* Length of name         */

       struct iovec *  msg_iov; /* Data blocks               */

       __kernel_size_t      msg_iovlen;    /* Number of blocks             */

       void       *     msg_control;  /* Per protocol magic (eg BSD file descriptor passing) */

       __kernel_size_t      msg_controllen;     /* Length of cmsg list */

       unsigned  msg_flags;

};

4.      

5.        

原创粉丝点击