最近把6.s081的所有lab都完成了,突然发现自己还没分享过完成lab的过程。笔者打算最近把所有lab的完成历程都整理下发布出来,避免后来者继续踩坑。
风让云长出花漫天的花
无声开在乌云之下
然后又飘到哪里呀
——飞云之下
说实话感觉professor上课没把tx_ring和rx_ring讲明白,重点都在讲各种网卡结构。完成lab要关注重点还是《E1000软件开发人员手册》的3.2和3.3节。而且这次的实验说明也要全文仔细阅读。
这里首先理一下下面两个数组的关系
static struct tx_desc tx_ring[TX_RING_SIZE] __attribute__((aligned(16)));
static struct mbuf *tx_mbufs[TX_RING_SIZE];
tx_ring是一个发送环,mbuf存的是一块指向数据包缓冲区的内容。每个mbuf元素存储的地址可能是不连续的,但是tx_ring[i]每个元素存着tx_mbuf[i]->head,我们也可以通过tx_ring[i]来连续访问tx_mbufs[i]的内容。
tx_mbufs 和 tx_ring 是两个不同的数组,它们在网络驱动程序中扮演不同的角色。
- 1. tx_mbufs:
• tx_mbufs 是一个存储指向数据包缓冲区(mbuf)的指针的数组。
• 每个元素都指向一个数据包缓冲区,这些缓冲区用于存储待发送的数据包的内容。
• 在发送数据包之前,驱动程序需要从 tx_mbufs 中选择一个缓冲区,并将数据包内容填充到该缓冲区中。
- 2. tx_ring:
• tx_ring 是用于存储传输描述符的数组。
• 每个传输描述符指向 tx_mbufs 中的一个数据包缓冲区,并包含有关要发送的数据包的元数据信息。
• 驱动程序通过填充传输描述符来指定要发送的数据包,并将其添加到 tx_ring 中。
• 一旦数据包被发送,传输描述符就会相应地更新,以便在发送过程中进行管理和跟踪。
因此,tx_mbufs 主要用于存储实际的数据包内容,而 tx_ring 则用于管理和控制将要发送的数据包以及发送过程中的状态。
tx_ring的结构如下:
阴影框表示已传输但尚未被软件回收的描述符。回收涉及释放与描述符关联的缓冲区。
发送描述符环由以下寄存器描述:
- 发送描述符基地址寄存器(TDBAL 和 TDBAH) 这些寄存器指示描述符环形缓冲区的开始。该 64 位地址在 16 字节边界上对齐,并存储在两个连续的 32 位寄存器中。 TDBAL 包含低 32 位; TDBAH 包含高 32 位。硬件忽略 TDBAL 中的低 4 位。
- 发送描述符长度寄存器(TDLEN) 该寄存器确定分配给循环缓冲区的字节数。该值必须是 128 字节对齐。
- 发送描述符头寄存器 (TDH) 该寄存器保存一个相对基址的偏移值,并指示正在进行的描述符。循环缓冲区中最多可以有 64K 描述符。读取该寄存器返回与已加载到输出 FIFO 中的描述符相对应的“head”值。
- 发送描述符尾部寄存器 (TDT) 该寄存器保存一个相对于基址的偏移量的值,并指示超出硬件可以处理的最后一个描述符的位置。这是软件写入第一个新描述符的位置。
弄明白tx_ring和tx_mbufs后,我们再来分析tx_desc的具体内容。
tx_desc是发送环DMA的数据结构,发送描述符是用于管理网络数据包发送的数据结构。
1. Addr:表示待发送数据包的起始地址。在内存中,这个地址指向了待发送数据包的数据缓冲区。
2. Length:表示待发送数据包的长度,通常以字节为单位
3. CSO:表示checksum offset。用于存储校验和的偏移量
4. CMD:用于存储发送描述符的控制命令,例如指示数据包是否最后一个数据包
5. STATUS:用于存储发送描述符的状态,例如描述符是否已经处理完成
6. CSS:表示checksum start。用于存储校验和开始的位置,与CSO字段一起使用,指示了校验和的起始位置和结束位置
7. Special:略
其中重点需要关注的是CMD字段。
IDE (bit 7) | 启用中断延迟 当设置时,激活传输中断延迟定时器。以太网控制器在写回具有RS和IDE设置的传输描述符时加载倒计时寄存器。加载的值来自中断延迟(TIDV)寄存器的IDV字段。当计数达到0时,如果启用了传输描述符写回中断(IMS.TXDW),则会发生传输中断。硬件始终在处理具有IDE设置的描述符时加载传输中断计数器,即使由于先前的描述符而已经在倒计时。如果硬件遇到具有RS设置但不具有IDE的描述符,则在写回描述符后立即生成中断。中断延迟计时器被清除。 |
VLE (bit 6) | 启用VLAN报文 当设置时,表示该报文是一个VLAN报文,以太网控制器应向报文添加VLAN以太类型和802.1q VLAN标记。以太类型字段来自VET寄存器,VLAN标记来自TX描述符的特殊字段。在这种情况下,硬件会插入FCS/CRC字段。 当清除时,以太网控制器发送一个通用以太网报文。在这种情况下,IFCS控制FCS字段的插入。 为了具有这种功能,CTRL.VME位也应设置,否则将忽略VLE功能。只有在设置了EOP时,VLE才有效。 |
DEXT (bit 5) | Extension (0b for legacy mode). Should be written with 0b for future compatibility |
RPS RSV (bit 4) | 报告数据包已发送 当设置时,82544GC/EI推迟写入状态字节(DESC.STATUS)中的DD位,直到数据包已发送或传输结果出现错误,例如过多的碰撞。在软件必须知道数据包已发送而不仅仅是加载到传输FIFO的情况下使用。82544GC/EI在设置了RPS的描述符后逻辑上可能会继续预取数据,但不会推进描述符头指针或写回任何其他描述符,直到使用RPS设置发送了数据包。只有在设置了EOP时,RPS才有效。 此位为保留位,除了82544GC/EI以外的所有以太网控制器都应将其设置为0b。 |
RS (bit 3) | 报告状态 当设置时,以太网控制器需要报告状态信息。此功能可供进行内存检查的软件使用,以确定哪些传输描述符已完成并且数据包已被缓冲在传输FIFO中。软件通过查看描述符状态字节并检查描述符完成(DD)位来执行此操作。 |
IC (bit 2) | 插入校验和 当设置时,以太网控制器需要在由CSO字段指示的偏移量处插入一个校验和。校验和计算是针对从由CCS字段指示的字节开始的整个数据包执行的。如果CSO和CCS超出数据包范围,则会忽略IC。这发生在(CSS ≥ 长度)或(CSO ≥ 长度 - 1)时。只有在设置了EOP时,IC才有效。 |
IFCS (bit 1) | 插入FCS 控制在普通以太网数据包中插入FCS/CRC字段。只有在设置了EOP时,IFCS才有效。 |
EOP (bit 0) | 数据包结束 当设置时,表示组成数据包的最后一个描述符。可以使用一个或多个描述符来形成一个数据包。 |
注:
- VLE、IFCS 和 IC 仅在设置了 EOP 时有效。也就是说,硬件只有在设置了 EOP 时才解释这些位。
- 硬件仅为设置了 RS 的描述符设置 DD 位。
- 具有空地址(0b)或零长度传输的描述符不传输任何数据。如果它们设置了 RS 位,则硬件在处理它们时会写入状态字中的 DD 字段。
- 尽管传输中断可能会延迟,但除非启用了描述符写回突发模式,否则通过设置 RS 位请求的描述符写回将立即执行,不会延迟。
STATUS字段存储适用的传输描述符状态,并具有表3-11中显示的字段。
只有在命令字段中设置了RS(对于仅适用于82544GC/EI的RPS)时,才存在传输描述符状态字段。
82544GC/EI 是 Intel 公司生产的一款以太网控制器芯片,通常用于构建网络接口卡(NIC)。这款芯片被设计用于支持千兆以太网(Gigabit Ethernet)标准,提供高速的网络连接。它支持各种特性,包括 VLAN 标记、流量控制、错误检测和校正等。
该芯片具有多种版本,其中 82544GC 是较为基本的版本,而 82544EI 则是增强型版本,提供更多的高级功能和性能优化。它们通常用于集成到网络接口卡或主板上,以实现高速网络连接和数据传输。
总的来说,82544GC/EI 是 Intel 公司为企业和数据中心等环境提供高性能网络解决方案而设计的一款以太网控制器芯片。
TU RSV (bit 3) | 表示发生了传输欠流事件。如果启用了早期传输(基于ETT.Txthreshold值),并且82544GC/EI由于数据包缓冲区中的数据不足而无法完成数据包的早期传输,则可能发生传输欠流。这并不一定意味着数据包最终未能传输。如果清除了TCTL.NRTU位(并且不发生过多的碰撞),则数据包将成功重新传输。 此位为保留位,除了82544GC/EI之外的所有以太网控制器都应将其编程为0b。 |
LC (bit 2) | 指示在半双工模式下发生了迟到的碰撞。在全双工模式下工作时,它没有意义。请注意,碰撞窗口取决于速度:10/100 Mb/s操作为64字节,1000 Mb/s操作为512字节。 |
EC (bit 1) | Excess Collision 指示数据包经历了超过由TCTL.CT控制字段定义的最大过多碰撞,并且未被传输。在全双工模式下工作时,它没有意义。 |
DD (bit 0) | Descriptor Done 表示描述符已完成,并在描述符已被处理(设置了RS)或对于82544GC/EI,在数据包已在传输线上传输后(设置了RPS)后写回。 |
注:DD位反映了包括设置了RS位(或对于82544GC/EI设置了RPS)的所有描述符的状态。
SPECIAL字段用于提供802.1q/802.1ac标记信息。
802.1Q 和 802.1ac 是 IEEE 标准中定义的两种 VLAN(虚拟局域网)标记协议。
-
802.1Q:IEEE 802.1Q 标准定义了一种 VLAN 标记协议,允许在以太网帧的头部添加额外的标签信息,以表示帧所属的 VLAN。这种标签信息包括 VLAN 标识符(VLAN ID),可以将以太网交换机上的端口划分为多个逻辑网络,以提高网络的安全性和管理性。VLAN ID 用于标识帧所属的 VLAN,从而实现虚拟化的局域网。
-
802.1ac:IEEE 802.1ac 标准是 802.1Q 的扩展,也称为 VLAN 标记协议的改进版本。它引入了更大的 VLAN 标签,允许在以太网帧的头部添加更多的标签信息,以支持更多的 VLAN 标识符。802.1ac 标准通常用于高密度 VLAN 部署,例如在数据中心网络中。
因此,当说到 "SPECIAL" 字段用于提供 802.1q/802.1ac 标记信息时,意味着该字段用于在网络数据帧中添加 VLAN 标签,以便在网络中识别和处理 VLAN。
当CTRL.VME设置为1b时,所有从以太网控制器发送的具有TDESC.CMD中设置了VLE的数据包都将附加一个802.1Q标头。标头的内容来自传输描述符的特殊字段和VLAN类型寄存器。如果传输描述符命令字段中的VLE位为0b,则将忽略特殊字段。特殊字段仅对TDESC.CMD中设置了EOP为1b的描述符有效。
PRI | User Priority 3 位,用于提供要插入到802.1Q标记中的VLAN用户优先级字段。 |
CFI | Canonical Form Indicator 规范形式指示器 |
VLAN | VLAN标识符 12 位,用于提供要插入到802.1Q标记中的VLAN标识符字段 |
rx的各种数据结构和tx类似,这里就不再赘述。