发布时间:2026/8/18 18:44:41
e1000收发包分析 前言上次看了 lan9118 收发包过程PIO 模式现代网卡基本千兆cpu直接搬运性能不太行了所以需要DMA开始看带dma的pci千兆网卡了能用qemu跑起来的重点看dma搬运用e1000经过查询发现有个 MIT 的著名操作系统课程 6.828 / 6.S081 的 Lab 就是让学生为 E1000 编写驱动网上有大量可以参考的学习资源就用这个吧vx6 网络实验目标DMA (Direct Memory Access)和描述符环 (Descriptor Ring)vx6 网络实验概念6.828 操作系统课xv6 操作系统做什么在 xv6 教学操作系统上亲手为一个E1000 网卡实现设备驱动。需要完成的核心任务有两个实现发送 (e1000_transmit)实现接收 (e1000_recv) 函数过程https://pdos.csail.mit.edu/6.828/2020/labs/net.html网页是英文但已有不少优秀的前辈做过这个实验还翻译成了中文可以直接搜索参考按照这个网页的步骤里面提供了一些参考资料如vx6的手册e1000的手册可以参考其中的哪些章节我看了然后发现自己还是不会写接收和发送函数于是决定给自己降低难度查找做过这个实验的前辈的代码我的任务是理解代码环境VMwareUbuntu 20.04_64尽量用较新的版本不然risv gcc工具链不太好搞安装库sudo apt install git sudo apt install make sudo apt install gcc sudo apt-get install git build-essential gdb-multiarch qemu-system-misc gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu sudo apt install vim下载 riscv64-elf-ubuntu-20.04-gcc-nightly-2023.09.27-nightly.tar.gz 这是编译好的二进制解压可以了。太早的版本只能下载源码编译编译尚未成功已放弃解压bin路径加入PATHtar -zxvf riscv64-elf-ubuntu-20.04-gcc-nightly-2023.09.27-nightly.tar.gz export PATH/....../riscv/bin:$PATH下载 vx6源码切到 net 分支git clone git://g.csail.mit.edu/xv6-labs-2020 git checkout net开始编译make clean make qemu然后就报错了user/sh.c:58:1: error: infinite recursion detected [-Werrorinfinite-recursion] 58 | runcmd(struct cmd *cmd) | ^~~~~~修改vim Makefile CFLAGS ... -Wno-infinite-recursion再次 make qumu可以啦xv6 kernel is booting hart 2 starting hart 1 starting init: starting sh $已进入 qemu退出 qemuctrla 松开再按x发包测试在一个终端cd xv6-labs-2020目录运行make server命令这启动了一个服务器程序监听来自 xv6 的 UDP 数据包另一个终端运行make qemu命令来启动 xv6 操作系统进到$后执行nettests命令这会向 IP 地址为10.0.2.2的“主机”发送一个 UDP 数据包。在 QEMU 的虚拟网络里10.0.2.2这个 IP 地址被映射到了真实主机Host。因此xv6 协议栈会调用e1000_transmit()函数来发送这个数据包直接执行是不可能收到回复的因为现在还没有实现发送函数 e1000_transmit()也没有实现 接收函数过程分析相关概念在实际看代码之前先来看些基本概念DMADMA直接内存访问的核心原理CPU 不搬运数据而是将“内存缓冲区地址”和“描述符环”的物理地址告诉网卡网卡内置的 DMA 控制器会通过 PCIe 总线自行读写这些物理内存。mbuf 数据包仓库tx/rx ring 地址簿 描述符发送描述符e1000 手册 3.3.3 表 3.9vx6里的简化相比 linux 内核定义【kernel/e1000_dev.h】 struct tx_desc { uint64 addr; uint16 length; uint8 cso; uint8 cmd; uint8 status; uint8 css; uint16 special; } // [E1000 3.2.3] struct rx_desc { uint64 addr; /* Address of the descriptors data buffer */ uint16 length; /* Length of data DMAed into data buffer */ uint16 csum; /* Packet checksum */ uint8 status; /* Descriptor status */ uint8 errors; /* Descriptor Errors */ uint16 special; };mbuf【kernel/net.h】 struct mbuf { struct mbuf *next; // the next mbuf in the chain char *head; // the current start position of the buffer unsigned int len; // the length of the buffer char buf[MBUF_SIZE]; // the backing store };初始化vx6的代码里提供了初始化函数e1000_init()e1000_init 把tx_ring数组首元素的地址写入 TDBAL ​ 数组长度写入 TDLEN ​ TDH写0 ​ TDT写0这里我就不贴代码了网上能直接搜索到只记录过程。发包过程网卡硬件提供e1000手册3.4​ 发送描述符基地址寄存器 TDBAL​ 发送描述符长度寄存器 TDLEN​ 发送描述符头存器 TDH​ 发送描述符尾存器 TDT软件​ 定义 tx_ring[]​ e1000_init​ 把tx_ring数组首元素的地址写入 TDBAL​ 数组长度写入 TDLEN​ TDH写0​ TDT写0​ 发送函数​ 接收协议栈组装好的 mbuf​ 读TDT知道可用的描述位置即tx_ring数组下标发第1个包是0一次加1​ 用下标在tx_ring数组里取到 描述符 desc​ 检查 desc 里 DD位1表示desc对应的上一个数据包已处理完成完成​ 释放旧的 mbuf​ 用mbuf里的信息填充 desc 数据包的内存地址长度​ mbufer地址保存到 tx_mbufs数组用于下次使用前释放内存​ 更新 TDT硬件​ **网卡硬件内部的状态机FSM**轮询发现 TDT ! TDH​ 从当前TDH指向的位置读取描述符Descriptor的内容地址、长度、CMD 位。​ 解析出addr和length。​ 发起PCIe 读事务DMA 读去内存中读取实际的mbuf数据。​ 数据读回来放入网卡内部的 FIFO再通过网线发出去​回写描述符的status字段: 置位E1000_TXD_STAT_DDDescriptor Done位。收包过程网卡硬件提供​ RDH 硬件下一个要写的位置​接收尾指针寄存器RDT指向的是“驱动已经处理并回填好的最后一个描述符的索引”软件​ 定义 rx_ring[]​ 定义 rx_mbufs[]​ e1000_init​ 把rx_ring数组首元素的地址写入 RDBAL​ 数组长度写入 RDLEN​ RDH写0​ RDT写 RX_RING_SIZE - 1​ 接收函数e1000_intr e1000_recv e1000_recv while(1) 根据 RDT 得到 rx_index 用 rx_index 得到 rx_ring[rx_index] 描述符 判断描述符的 DD //网卡硬件在将数据包 DMA 搬运到内存完成后由网卡硬件自动置 1 的标志位 0 break 1 继续向下执行 用描述符-length 更新 rx_mbufs[rx_index]-len net_rx 把数据 rx_mbufs[rx_index] 给到协议栈 分配新 mbuf 更新 desc-addr 清除 desc-status 0 更新 RDT总结接收包完整过程e1000驱动初始化基址预填所有空仓库​ rx_ring数组首元素的地址写入 RDBAL​ 用mbufalloc()分配好所有空mbuf把它们的物理地址head一个一个填进rx_ring里每个描述符的addr字段。当数据包从网线进入网卡​ 网卡硬件DMA根据RDH找到用rx_ring[]里哪个描述符​ 从描述符里读出物理地址把数据搬运到对应物理地址​ 描述符DD写1中断通知cpucpu用注册好的中断函数处理e1000_intr调用接收函数接收函数​ 传递 **mbuf结构体的指针虚拟地址**给到了协议栈net.c而不是物理地址​ 分配新的mbuf​ 把新mbuf的物理地址填回同一个描述符。​ 清空status去掉DD​更新RDT协议栈​ 通过**mbuf结构体的指针虚拟地址**去读取mbuf-head里面存的才是物理地址但协议栈不需要知道因为 xv6 做了直接映射虚拟地址可以直接加减偏移得到物理地址参考vx6 网络实验 https://pdos.csail.mit.edu/6.828/2020/labs/net.html

相关新闻

2026/8/18 18:44:41

std::variant与std::visit:从访问者模式到类型安全联合

访问者&#xff08;Visitor&#xff09;模式想解决的是&#xff1a;有一族结构相对稳定的类型&#xff0c;上面要挂多种易变的操作&#xff08;求值、打印、序列化……&#xff09;&#xff0c;又不想在每个类里无限加成员函数&#xff0c;也不想用一长串 if (dynamic_cast<…

2026/8/18 18:39:41

GLYKEN可莱康二十年产业积累,探索燕窝肽健康产业新未来

近年来&#xff0c;随着消费者对健康意识的日益提高&#xff0c;大健康产业正在迎来一次重要的转型&#xff0c;正从传统滋补迈向科学营养和日常管理的新阶段。在这样的背景下&#xff0c;GLYKEN&#xff08;可莱康&#xff09;在燕窝肽领域全力以赴&#xff0c;借助科技创新为…

2026/8/18 19:49:51

Java学习笔记(二):类型转换

类型转换类型从低到高byte&#xff0c;short&#xff0c;char -> int -> long - > float -> doubleJava是强类型语言&#xff0c;运算中不同类型数据要转化成同一类型再运算。强制类型转换public class Demo{public static void main(String[] args){int i 128;by…

2026/8/18 19:49:51

Java学习笔记(三):变量、常量、作用域

变量、常量、作用域变量type varName value; // 数据类型 变量名 值&#xff1b;可以使用逗号来声明多个同类型变量。注意事项每个变量都有类型&#xff0c;类型可以是基础类型&#xff0c;也可以是引用类型。变量名必须是合法的标识符。变量声明是一条完整语句&#xff0c;因…

2026/8/17 10:49:52

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/18 6:58:27

工业传感器与变送器详解:序章 从物理世界到工业数据

序章 从物理世界到工业数据 ——重新认识工业传感器与变送器 工业自动化系统正变得日益复杂。今天的工业现场早已不是简单的控制回路,而是由多层技术共同构成的立体体系:PLC、DCS、SCADA、MES、工业互联网、边缘计算与人工智能。控制系统可以执行复杂算法,工业网络可以实现…

2026/8/18 0:02:05

Qwen3.8-27B本地部署实战:17GB内存运行270亿参数大模型

1. 这篇文章真正要解决的问题 你是否曾对动辄需要上百GB显存才能运行的百亿参数大模型望而却步&#xff1f;是否觉得在个人电脑上部署一个功能强大的语言模型是天方夜谭&#xff1f;最近&#xff0c;通义千问团队发布的 Qwen3.8-27B 模型&#xff0c;宣称仅需 17GB 内存即可在本…

2026/8/18 0:02:05

ME3169 36V,8A,180KHz 恒压Buck DC-DC 转换器

概述ME3169 是一款180KHz&#xff0c;PWM 模式恒压Buck DC-DC 转换器&#xff0c;8V 到36V 宽工作电压范围&#xff0c;低纹波&#xff0c;内置低导通电阻功率MOS。ME3169 内置环路补偿电路&#xff0c;可以减少外围元器件数量。内部设计有恒压环路&#xff0c;可以通过外部电阻…

2026/8/18 18:23:10

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站&#xff0c;核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测&#xff0c;千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队&#xff0c;覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/17 17:27:06

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站&#xff0c;核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测&#xff0c;千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队&#xff0c;覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/18 7:12:40

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具&#xff0c;覆盖选题构思、文献整理、内容生成、格式排版等核心场景&#xff0c;真正帮你高效搞定论文难题。 一、全流程王者&#xff1a;一站式搞定论文全链路&#xff08;一天定稿首…