lab11 net

image-20230830133205600

background

  1. 在开始写代码之前,回顾一下xv6book的第五章会有帮助
  2. 你将使用E1000去处理网络通信
    1. E1000会和qemu模拟的lan通信
    2. 在qemu模拟的lan中
      1. xv6的地址是10.0.2.15
      2. qemu模拟的计算机的地址是10.0.2.2
  3. qemu会将所有的网络包都记录在packets.pcap
  4. 文件kernel/e1000.c包含了E1000的初始化代码,以及你需要补充的接收和发送的空函数
  5. kernel/e1000_dev.h包含了寄存器和标志位的定义
  6. kernel/net.ckernel/net.h包含了一个简单的内核栈去实现IP,UDP,ARP协议。这些文件也包含了一个灵活的数据结构去持有packet,叫作mbuf

your job

  1. 完成kernel/e1000.c中的e1000_transmit()e1000_recv()

简单捋一下实验的思路

  1. 首先,我们要修改的是设备驱动,也就是内核层面的代码,它会和硬件设备协同完成数据包的发送和接受
  2. 发送数据包时
    1. 内核只需要将已经准备好的mbuf放到一个缓冲数组中,就完事了。这就是缓冲数组的优点,我往里面一扔就行了
    2. 网卡中应该也有固定的程序,它会自己讲缓冲数组的数据包给发送出去
    3. 我们只需要完成1中的任务,网卡那边不需要我们管
  3. 接受数据包时
    1. 当网卡接收了数据时,它会将它存入另一个缓冲数组,存好之后它们通过一个中断,告诉内核来收数据了
    2. 内核只需要将这个缓冲数组中已经到达的数据包传递给上层应用即可

以上就是基本的交互框架,但是因为设备驱动是内核,是纯软件,而网卡设备是硬件,所以双方的交互就有点麻烦。这里通过了一个很神奇的操作,就是寄存器映射,将硬件的寄存器给映射到了内核的地址空间中,我们访问内核的某个地址,就是在访问硬件的寄存器,这一下子就打通了内核和硬件之间的桥梁

e1000_init中,就将寄存器映射的起始地址赋值给了regs,并且将各种信息和地址都存放到寄存器中,比如数组tx_ring的地址就放到了regs[E1000_TDBAL] = (uint64)tx_ring;

至此,准备工作就做完了,我们现在就需要增加内核代码,使其能够和网卡配合,完成数据报的发送和接受

hints:e1000_transmit

这个lab很有意思,它的hints基本就是给了你所有的伪代码,你一个一个去实现就行了

  1. 首先,让我们通过E1000_TDT为索引去regs取出当前的index,其中regs就是一个uint类型的数组的头指针
  2. 判断这个index指向的buf的状态,通过这个index去tx_ring中取出des,状态就存于des里的status中。这里要和一个宏E1000_TXD_STAT_DD相与进行判断
  3. 如果这个buf还存着之前的值,将它通过mbuffree给free掉
  4. 按提示修改des的各种参数,并且当前buf修改为传入的参数m即可。其中des的cmd参数没有给出提示,估计是想让我们自己查手册,我直接抄了大佬的E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS
  5. 最后,更新寄存器的值(空闲buf的指针,也就是第1步取出来东西的那个寄存器)

这里有个注意点就是,需要在函数首尾加锁。因为同一时刻,可能有多个进程想要通过网卡发送数据,这就形成了竞争的问题

int e1000_transmit(struct mbuf *m) {//// Your code here.//// the mbuf contains an ethernet frame; program it into// the TX descriptor ring so that the e1000 sends it. Stash// a pointer so that it can be freed after sending.//acquire(&e1000_lock);uint32 index = regs[E1000_TDT];struct tx_desc *des = &tx_ring[index];if (!(des->status & E1000_TXD_STAT_DD)) {release(&e1000_lock);return -1;}if (tx_mbufs[index]) {mbuffree(tx_mbufs[index]);}des->addr = (uint64)m->head;des->length = m->len;des->cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS;tx_mbufs[index] = m;regs[E1000_TDT] = (regs[E1000_TDT] + 1) % TX_RING_SIZE;release(&e1000_lock);return 0;
}

hints:e1000_recv

  1. 首先通过寄存器中E1000_RDT的值+1对RX_RING_SIZE取模获取待接收数据的索引
  2. 判断这个索引指向的buf的状态是否是待接收
  3. 如果是待接收,修改m->len并且通过net_rx将这个buf传递给上层
  4. 通过mbufalloc在这个索引处再次新建一个buf,并且将这个buf的des的data指针指向这个buf的head,然后将状态设置为0
  5. 最后将这个索引的寄存器的值+1,

这里有两个注意点

  1. 不需要加锁,因为这里给出了提示。如果这个函数没有运行完,那么不会产生另一个中断
void e1000_intr(void) {// tell the e1000 we've seen this interrupt;// without this the e1000 won't raise any// further interrupts.regs[E1000_ICR] = 0xffffffff;e1000_recv();
}
  1. 需要使用while循环,把能读的数据包都读出来。我猜是因为一次中断不一定代表只有一个数据包到了,甚至在处理中断的过程中,还会有数据包到。如果每次中断只读一个,会导致丢很多包

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/90511.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker 中下载各版本的 CentOS、CentOS Steam 方式

如果你跟我一样,想要在docker下载centos的镜像,但是无奈访问不了 https://hub.docker.com/,于是不知道有哪些tag可以下载,该如何办呢? 方法如下,以供参考。 访问:https://quay.io/repository/…

器件手册识读之 :运放

器件手册识读之 :运放 一、基本信息 二、引脚排列 三、最大额定参数 四、电气特性 五、应用电路 1、称重传感器放大器 2、热电偶低偏置,低漂移环路测量二极管冷端补偿。

【LeetCode】409. 最长回文串

409. 最长回文串(简单) 方法:哈希表 贪心 思路 不难发现,回文字符串一定是由 若干偶数个字符 至多一个奇数个字符 组成 。我们可以使用一个长度为 128 的 hash表来记录每一个字符的出现次数,当该字符出现了两次&am…

Java 复习笔记 - 方法篇

文章目录 一,方法的定义二,最简单的方法定义和调用三,带参数的方法定义和调用四,带返回值方法的定义和调用五,小结六,方法的重载七,方法简单练习1,数组遍历2,数组最大值3…

大彩串口屏使用记录

写在最前面 屏幕型号 DC10600M070 IDE VisualTFT(官方) VSCode(lua编程) 用之前看一下官方那个1小时的视频教程就大概懂控件怎么用了,用官方的软件VisualTFT很简单 本文只是简单记录遇到的一些坑 lua编辑器 VisualTF…

【安装GPU版本pytorch,torch.cuda.is_available()仍然返回False问题】

TOC 第一步 检查cuda是否安装,CUDA环境变量是否正确设置,比如linux需要设置在PATH,window下环境变量编辑看看,是否有CUDA 第二步,核查python中torch版本 首先查看你环境里的pytorch是否是cuda版本,我这…

ZooKeeper技术内幕

从系统模型、序列化与协议、客户端工作原理、会话、服务端工作原理以及数据存储等方面来向揭示ZooKeeper的技术内幕,更深入地了解ZooKeeper这一分布式协调框架。 1、系统模型 将从数据模型、节点特性、版本、Watcher和ACL五方面来讲述ZooKeeper的系统模型。 1.1、…

简易虚拟培训系统-UI控件的应用4

目录 Slider组件的常用参数 示例-使用Slider控制主轴 示例-Slider控制溜板箱的移动 本文以操作面板为例,介绍使用Slider控件控制开关和速度。 Slider组件的常用参数 Slider组件下面包含了3个子节点,都是Image组件,负责Slider的背景、填充区…

数据结构1 -- leetcode练习

三. 练习 3.1 时间复杂度 用函数 f ( n ) f(n) f(n) 表示算法效率与数据规模的关系,假设每次解决问题需要 1 微秒( 1 0 − 6 10^{-6} 10−6 秒),进行估算: 如果 f ( n ) n 2 f(n) n^2 f(n)n2 那么 1 秒能解决多…

【设计模式】装饰者模式

目录 一、定义二、结构三、优点四、使用场景五、代码示例六、截图示例 一、定义 1.在不改变现有对象结构的情况下,动态给该对象添加额外功能的模式 2.类B继承于类A,并将类A作为B类的属性(B类聚合A类) 3.BufferedInputStream、Buff…

C语言(第三十天)

1. 什么是bug bug本意是昆虫”或“虫子”,现在一般是指在电脑系统或程序中,隐藏着的一些未被发现的缺陷或问 题,简称程序漏洞。 “Bug” 的创始人格蕾丝赫柏(Grace Murray Hopper),她是一位为美国海军工作的…

搭建个人备忘录中心服务memos、轻量级笔记服务

目录 一、源码 二、官网 三、搭建 四、使用 一、源码 GitHub - usememos/memos: A privacy-first, lightweight note-taking service. Easily capture and share your great thoughts. 二、官网 memos - Easily capture and share your great thoughts 三、搭建 docke…