Linux Kernel TCP/IP Stack — 协议栈初始化处理流程

举报
云物互联 发表于 2021/08/06 22:33:59 2021/08/06
【摘要】 目录 文章目录 目录网络协议栈初始化流程1、内核启动2、初始化网络子系统3、初始化网卡驱动4、启动网卡 网络协议栈初始化流程 这需要从 Kernel 的启动流程说起。 1、内核启动 当 Kernel 完成自解压过程后就进入了 Kernel Start 流程,实现在 arch/mips/kernel/head.S 程序中。这个程序负责 BBS(数...

目录

网络协议栈初始化流程

这需要从 Kernel 的启动流程说起。

1、内核启动

当 Kernel 完成自解压过程后就进入了 Kernel Start 流程,实现在 arch/mips/kernel/head.S 程序中。这个程序负责 BBS(数据区)、IDT(中断描述表)、GDT(段描述表)、Page Table(页表)、寄存器的初始化,程序中定义了 Kernel 的入口函数 kernel_entry()。kernel_entry() 函数是 CPU 体系结构相关的汇编代码,它首先初始化内核堆栈段为创建系统中的第一过程进行准备,接着用一段循环将 Kernel Image 的未初始化的数据段清零,最后跳到 start_kernel() 函数中执行硬件初始化相关的代码,完成 Linux Kernel ENV 的建立。

start_kenrel() 定义在 init/main.c 中,真正的 Kernel 初始化过程就是从这里才开始。函数 start_kerenl() 将会调用一系列的初始化函数,包括:平台初始化,内存初始化,陷阱初始化,中断初始化,进程调度初始化,缓冲区初始化,完成内核本身的各方面设置,目的是最终建立起基本完整的 Linux Kernel ENV。

start_kernel() 中主要函数及调用关系如下:

在这里插入图片描述

2、初始化网络子系统

其中,start_kernel() 过程中会执行 sock_init() 来完成 TCP/IP Stack 的初始化,实现如下:

在这里插入图片描述

sock_init() 包含了 TCP/IP Stack 的初始化工作:

  1. sock_init:Initialize sk_buff SLAB cache,注册 SOCKET 文件系统。
  2. proto_init:在 /proc/net 域下建立 protocols 文件,注册相关的文件操作函数。
  3. net_dev_init:建立 netdevice 在 /proc/sys 相关的数据结构,并且开启网卡收发中断;为每个 CPU 初始化一个数据包接收队列(softnet_data),包接收的回调;注册 lo 本地回环操作,注册默认网络设备操作。
  4. inet_proto_init:注册 INET 协议族的 SOCKET 创建方法,注册 TCP、UDP、ICMP、IGMP 接口基本的收包方法。为 IPv4 协议族创建 proc 文件。
  5. unix_proto_init:注册 UNIX Socket。

TCP/IP Stack 的初始化完成后再执行 dev_init() 函数,继续设备的初始化。

3、初始化网卡驱动

每个网络驱动程序(NIC Controller)会使用 module_init() 向 Kernel 注册一个 Init 函数,当驱动被加载时,Kernel 会调用这个函数。例如:igb 网卡的初始化函数 igb_init_module()。

// file: drivers/net/ethernet/intel/igb/igb_main.c

static int __init igb_init_module(void){ ...... ret = pci_register_driver(&igb_driver); return ret;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

网卡驱动的 pci_register_driver() 调用完成后,Linux Kernel 就知道了该驱动的相关信息了,包括:igb 网卡驱动的 igb_driver_name 和 igb_probe() 函数的地址等。

当网卡设备被 Kernel 识别以后,Kernel 会调用其驱动的 Probe(探针)函数,例如:igb_driver 的 Probe 函数是 igb_probe()。该函数的目的是为了让网卡设备 Ready(就绪)的。

在这里插入图片描述

  1. 获取 NIC 的 MAC 地址。

  2. 初始化 RAM 分配给 NIC Controller 的 DMA 存储空间。

  3. 注册 NIC Controller 提供的 ethtool 实现函数,当我们执行 ethtool CLI 发起一个 System Call 时,Kernel 就会回调这个注册函数。ethtool CLI 之所以能够查看 NIC 的收发包统计、修改 NIC 的自适应模式、调整 RX queue 的大小,就是因为 ethtool CLI 最终调用到了 NIC Controller 提供的相应函数。

  4. 注册的 igb_netdev_ops() 中包含了 igb_open() 等函数,在 NIC 被启动时调用。

  5. 注册一个 NAPI(中断 + 轮询)收包机制所必须的 poll() 函数到 ksoftirqd 内核线程。例如:igb 网卡驱动实现的 igb_poll()

如此的,NIC Controller 所必须提供的注册函数就都被注册到 Kernel 了,Kernel 会在网络处理流程中回掉这些函数,以此实现对 NIC 的控制。

4、启动网卡

在这里插入图片描述

当我们执行 ifconfig eth0 up 类型的网卡启动 CLI,Kernel 就会执行 net_device_ops 变量中所包含的:网卡启用、收/发包、设置 MAC 地址等回调函数(函数指针)。并执行:

  1. 分配 Rx/Tx Ring Buffer FIFO queue。
  2. 注册 NIC Controller 提供的硬中断处理函数到 Kernel。
  3. 打开硬中断,等到数据帧的到来。

文章来源: is-cloud.blog.csdn.net,作者:范桂飓,版权归原作者所有,如需转载,请联系作者。

原文链接:is-cloud.blog.csdn.net/article/details/102996612

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。