23 网络数据在内核中流转

发布时间 2023-05-03 16:06:37作者: QianFa01

一次具体的网络收发过程:

发送过程:

应用程序准备好数据,调用用户态下的库函数,调用系统API接口函数,进入到内核态;内核态对应的系统服务函数会复制应用程序的数据到内核的内存空间中,然后将数据移交给网络协议栈,在网络协议栈中将数据层层打包;最后,包装好的数据会交给网卡驱动,网卡驱动程序负责将打包好的数据写入网卡并让其发送出去;

接收过程:

网卡接收到数据,通过DMA方式复制到指定的内存,接着发送中断,以便通知网卡驱动,由网卡驱动处理中断复制数据;然后网络协议收到网卡驱动传过来的数据,层层解包,获取真正的数据;最后将这个数据发送到用户态监听的应用进程;

      

LwIP架构:light weight IP

TCP/IP协议的轻量级开源项目;C语言实现的,一共有两套接口层,向上提供给用户,向下提供给系统;保持TCP协议主要功能 的基础上减少对 RAM的占用;同时,还支持ipv6 标准实现;

LwIP结构分为四层:OS层,API层,核心层,硬件驱动层;

第一层:通过netconn 或 lwip_api 使用 lwip 的各种功能函数;

第二层:api层是netconn的功能代码所在的层;

第三层:lwip的核心层存放了TCP/IP协议的核心代码;实现TCP、UDP功能,还实现了 DNS、ICMP、IGMP等协议;同时也实现 了内存管理、网络接口功能;sys_arch模块便于移植到不同的OS上;

第四层:硬件驱动层提供PHY芯片驱动,用来匹配 lwip 的使用;lwip会调用该层的代码将组装好的 数据包发送到网络;同时从网络接收数据包并进行分析,实现通信功能;

lwip的三套应用程序编程接口:

RAW/Callback API、顺序 API 和 Socket API;

lwip 执行流程:

数据发送:

把lwip 作为 cosmos 的一个内核组件来工作;由 lwip 接收来自内核上层发来的数据,内核上层先调用lwip的netconn层的接口函数 netconn_write 函数,数据正式流进lwip 组件层;

接着,netconn层调用 lwip 组件的tcp层的接口函数tcp_write ,在tcp层对数据首次进行打包,然后tcp层将打包好的数据通过io_output 函数,向下传递给lwip组件的IP层,进行打包;

最后,IP层将打包的数据发送给网卡驱动接口层netif ,调用实际的网卡驱动程序,将数据发送出去;

    

数据接收:

应用程序首先调用 lwip 的netconn 层的 netconn_recv接口,然后由 netconn 层调用sys_arch_mbox_fetch 函数,进入监听等待相关的mbox;

接着,数据会进入网卡,驱动程序相关的函数负责把它复制到内存;再然后是调用ethernet_input 函数,进入ethernet 层;调用ip4_input 函数,数据在lwip组件ip层对数据解包,进行相应的处理,还会调用tcp_input 函数,进入lwip 组件的tcp 层对数据解包;

最后,调用 sys_mbox_trypost 函数把数据放入特定的 mbox,等待监听的应用程序得到数据;

协议栈移植:

有两种:无操作系统模式、有操作系统模式(sys_arch 层的接口函数);

带操作系统的移植就是无操作系统的基础上添加操作系统的模拟层;

操作系统主要基于操作系统的 IPC机制(Inter-process Communication,进程间通信),对网络连接进行了抽象,保证内核与应用层API的通讯,好处是lwip 内核线程可以只负责数据包的TCP/IP的封装和拆封,不用进行数据的应用层处理,极大提高系统对网络数据包的处理效率;

有操作系统的模式:

完整的移植网络栈,需要移植30多个函数实现;这些变量和函数主要面向信号量,互斥体和邮箱,包括创建删除、释放和获取等操作;

在lwip中,用户代码通过邮箱与协议栈内部交互,邮箱本质上是指向数据的指针;API 将指针传递给内核,内核通过这个指针访问数据,然后进行处理;内核也是通过邮箱将数据传递给用户代码的;