Linux驱动开发-网络设备驱动
- 一,网络设备总体结构
-
- [1.1 总体架构](#1.1 总体架构)
- [1.2 NAPI数据处理机制](#1.2 NAPI数据处理机制)
- 二,RMII和MDIO
-
- [2.1 RMII接口](#2.1 RMII接口)
- [2.2 MDIO接口](#2.2 MDIO接口)
- 三,MAC和PHY模块
-
- [3.1 MAC模块](#3.1 MAC模块)
- [3.2 PHY模块](#3.2 PHY模块)
- 四,网络模型
-
- [4.1 网络的OSI和TCP/IP分层模型](#4.1 网络的OSI和TCP/IP分层模型)
-
- [4.1.1 传输层:TCP和UDP](#4.1.1 传输层:TCP和UDP)
-
- [4.1.1.1 TCP](#4.1.1.1 TCP)
-
- [① 三次握手](#① 三次握手)
- [② 确认机制](#② 确认机制)
- [③ 四次挥手](#③ 四次挥手)
- [4.1.1.2 UDP](#4.1.1.2 UDP)
- [4.1.2 网络层](#4.1.2 网络层)
- [4.1.3 物理链路层](#4.1.3 物理链路层)
一,网络设备总体结构
1.1 总体架构
SOC即主控芯片,目前大部分内部集成MAC模块,通过RMII和PHY芯片连接,RMII接口进行的是网络数据的传输,MDIO总线,设置PHY芯片寄存器。
1.2 NAPI数据处理机制
比如现在有网络数据输入,不可能一有数据传输过来,就执行中断,那么会一直占据中断,消耗CPU处理时间,如果采用轮询的方式,每隔一定时间查询一下是不是有数据了,这样处理就不及时。因此出现NAPI(New API)技术,将中断和轮询结合,采用中断唤醒数据接收服务程序,在中断接收服务程序中采用轮询的方式处理数据,提高数据包接收效率,减少中断处理时间。
二,RMII和MDIO
2.1 RMII接口
RMII(Reduced Media Independent Interface),是MII接口的精简版本,相对于MII少了9跟线,方便板子布线。
TX_EN :发送使能信号。
TXD[1:0] :发送数据信号线,两根。
RXD[1:0] :接收数据信号线,两根。
CRS_DV :接收数据有效和载波侦听信号结合。
REF_CLK:参考时钟,由外部时钟源提供,频率为50MHZ。
2.2 MDIO接口
MDIO(Management Data Input/Output),即管理数据输入输出接口,两线串行接口,一根MDIO数据线,一根MDC时钟线。PHY驱动通过这两根线,访问PHY上面的任意寄存器,PHY驱动也可以通过这两根线,连接最多32个PHY,保证每个PHY器件地址不同,同一时刻只能对一个PHY芯片进行操作,类似于I2C,由下面的读写操作,和I2C读写不一样的,不过大体上相似。
数据帧(32位) :| 前导码(32位) | ST(2) | OP(2) | PHYAD(5) | REGAD(5) | TA(2) | DATA(16) |
ST(Start) :01表示帧开始。
OP(Operation) :10表示写,01表示读。
PHYAD :PHY地址(0-31),因为是5位,因此有32种结果,十进制的话就是0到31。
REGAD :寄存器地址(0-31)。
TA(Turnaround) :读操作时MDIO方向切换周期。
DATA :16位读写数据。
写操作:①拉高MDIO,生成MDC时钟②发送32位全为1的前导码③发送起始位01④发送操作码,10表示写⑤发送PHY地址⑥发送寄存器地址⑦发送两位10TA,表示不用切换方向⑧发送16位数据⑨MDIO释放总线
读操作:①发送前导码和起始位②发送操作码01,表示读③发送PHY地址④发送寄存器地址⑤发送TA,切换数据传输方向⑥PHY设备MDIO返回两位TA(00)+16位数据⑦释放总线
三,MAC和PHY模块
3.1 MAC模块
即底层网络数据处理的驱动程序,整体围绕net_device这个具体网络设备,采用的是platform 驱动框架,创建出fec_driver结构体,包含probe函数和remove函数,probe函数主要是注册和初始化的相关工作,具体对数据的处理在ops操作函数里面,当打开网卡时,fec_enet_open函数执行,申请数据缓冲区,包括发送队列和接收队列缓冲区,探测并连接对应的PHY设备,使能NAPI调度,开启PHY设备,激活发送队列等工作。应用层有数据要发送,即sk_buff,会触发中断,中断函数中对NAPI进行调度,使能NAPI的poll轮询函数,类似于中断的上半部和下半部处理机制,在轮询函数中,真正的对数据进行处理,sk_buff一般会被网卡或者协议栈进行分段处理(数据包较大)。
3.2 PHY模块
采用的是设备,总线,驱动框架,即PHY设备驱动,MDIO总线,PHY具体设备。phy_driver表示驱动,采用phy_device表示PHY设备,函数get_phy_device获取PHY设备,具体内容包括:获取PHY ID,对phy_device结构体中的成员进行初始化,总线有相应的文件。
四,网络模型
4.1 网络的OSI和TCP/IP分层模型

4.1.1 传输层:TCP和UDP

4.1.1.1 TCP
Source Port :源端口,标识哪个应用程序发送,16bit。
Destination Port :目的端口,标识哪个应用程序接收,16bit。
比如浏览网页**,客户端网页浏览器向 服务器网站**请求下载网页,客户端向服务器发了一个请求报文,这个报文的源端口就是客户网页浏览器的端口,目的端口就是网站服务器端口(HTTP应用)。
Sequence Number :序列号字段,每个TCP报文都有序列号,32bit。
Acknowledgment Number :确认号,对收到的报文进行确认,序列号和确认号,是为了保证每个发送过去的包,对方都能收到,我发出一个带有序列号的包,对方就要回一个带有确认号的包,这俩号是有一定关系的。
Header Length :头部长度,TCP报文头部长度,不是数据长度。
Control bits :控制位,有FIN,ACK,SYN标志位。
Window :窗口值,表示当前接收端能够接收的最大数据总数,以字节为单位,就是接收方告诉发送方,能接收的能力
Checksum :校验字段。
① 三次握手

三次握手是建立连接用的,SYN,ACK是控制位①PC1发送握手请求,SYN置位为1,序列号Seq为a,Ack为0,发送给PC2。②PC2接收到信号,要给PC1反馈个信息,让PC1知道PC2准备好了,并且PC2也想知道PC1是不是准备好了,发送一个序列号为b(任意),Ack信号为a+1(表示PC2准备好了)此时的控制位SYN和ACK置位。③PC1想让PC2知道,他也准备好了,于是会再反馈一个信号,序列号Seq为a+1(PC1的第一个信号a,因此下一个信号a+1),Ack信号为b+1(表示准备好了)。PC1准备好,PC2也准备好,就建立其连接。
② 确认机制

确认机制就是判断每个TCP的数据包,发送过去以后,对方是否能接收到。在三次握手建立连接后,PC1发送一个数据包,Seq为a+1,Ack为b+1,载荷长度为12,当PC2接收到这个数据包后,会给PC1反馈一个Seq为b+1,Ack为PC1的Seq(a+1)+载荷(12),即a+1+12,PC2的载荷为0,此数据包发送给PC1,表示PC2接收到PC1发送的数据包了。
③ 四次挥手

四次挥手是在发送结束时候用的,通信时双向的,当PC1发送结束,会给PC2发送一个数据包,控制位的FIN置位,ACK置位,序列号Seq=101,Ack=301,PC2接收到PC1这个数据结束的数据包,会给PC1发送一个Seq=PC1的Ack,即301,Ack为PC1的Seq(101)+1=102,此时控制位ACK置位。同样PC2发送完数据,也会和PC1这个过程类似。四次挥手后,TCP连接断开。
4.1.1.2 UDP
Source Port :源端口,标识哪个应用程序发送,16bit。
Destination Port :目的端口,标识哪个应用程序接收,16bit。
Length :报文总长度。
UDP模式加上端口号后,直接发送即可,不用在乎目的地址信息是否有反馈。
4.1.2 网络层
网络层接收到传输层发来的数据,会封装一个IP报文头部,把源IP地址和目的IP地址放到头部中,中间经过网络设备,比如路由器,路由器内部有路由表,读取IP数据包的目的IP地址,转发这个数据包。
4.1.3 物理链路层

传输层(网线,光纤)→网络层(路由器)→物理链路层(交换机)。在物理链路层,会给IP数据包,加上MAC地址,在交换机中,根据这个MAC地址,将数据包发送到具体设备,比如主机上。具体怎么获取MAC地址,是通过ARP请求,源Host A会给Host B发送一个ARP请求,带有Host B这个目的IP,Host B接收到这个ARP请求后,会反馈带有Host A的IP地址和Host B的MAC地址的数据包。
上述网络模型图,来自B站:网络工程师学长,https://www.bilibili.com/video/BV1P3411M7zF?p=13\&vd_source=a11372469703158c2d89e1da0b799875