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.rhkb.cn/news/112084.html

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

相关文章

【LeetCode-中等题】148. 排序链表

文章目录 题目方法一:集合排序(核心是内部的排序)方法二: 优先队列(核心也是内部的排序)方法三:归并排序(带递归) 从上往下方法四:归并排序(省去递…

java八股文面试[多线程]——什么是守护线程

知识来源: 【2023年面试】什么是守护线程_哔哩哔哩_bilibili

新亮点!安防视频监控/视频集中存储/云存储平台EasyCVR平台六分屏功能展示

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

WebRTC之FEC前向纠错协议

FEC前向纠错用于丢包恢复,对媒体包进行异或或其他算法生成冗余包进行发送。如果接收端出现丢包,可以通过冗余包恢复出原始的媒体包。FEC的代价是增加码率带宽,所以一般会根据网络状况、丢包率来动态调整FEC冗余系数,也会结合NACK/…

一文带你全面理解向量数据库

近些年来,向量数据库引起业界的广泛关注,一个相关事实是许多向量数据库初创公司在短期内就筹集到数百万美元的资金。 你很可能已经听说过向量数据库,但也许直到现在才真正关心向量数据库——至少,我想这就是你现在阅读本文的原因…

cvat 安装部署

官网地址: https://github.com/opencv/cvat/tree/masterhttps://github.com/opencv/cvat/tree/master 1.从官网上下载源码地址。 2.配置环境变量 vim /etc/profile source /etc/profile 或者执行: export CVAT_HOSTyour-ip-address 3.执行命令 …

基于Spring Boot 的 Ext JS 应用框架之coworkee

Ext JS 官方提供了一个人员管理的完整应用框架 - coworkee。该框架的显示如下: 该框架的布局特点如下: 布局方式: 左右布局, 左侧导航栏默认收合特点:左侧导航区占用空间小, 工作区较大, 适合没有二级导航栏,工作区需要显示的内容较多的系统。如果导航栏是横向底部,就…

ssm毕业生就业状况管理系统源码和论文

ssm毕业生就业状况管理系统源码和论文093 开发工具:idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 技术:ssm 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储&#xff…

无涯教程-Android - Grid View函数

Android GridView在二维滚动网格(行和列)中显示项目,并且网格项目不一定是预定的,但它们会使用ListAdapter自动插入到布局中 Grid View - Grid view ListView 和 GridView 是 AdapterView 的子类,可以通过将它们绑定到 Adapter 来填充&#x…

MongoDB实验——在MongoDB集合中查找文档

在MongoDB集合中查找文档 一、实验目的二、实验原理三、实验步骤1.启动MongoDB数据库、启动MongoDB Shell客户端2.数据准备-->person.json3.指定返回的键4 .包含或不包含 i n 或 in 或 in或nin、$elemMatch(匹配数组)5.OR 查询 $or6.Null、$exists7.…

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

目录 前言 UI结构总体介绍 建立初步的系统UI结构 Image控件 前言 前面的文章介绍了关于Oculus设备与UI控件的关联,从本文开始采用小示例的方式介绍基本的UI控件在系统中的基本作用(仅介绍“基本作用”,详细的API教程可参考官方文档&#x…

用wireshark流量分析的四个案例

目录 第一题 1 2 3 4 第二题 1 2 3. 第三题 1 2 第四题 1 2 3 第一题 题目: 1.黑客攻击的第一个受害主机的网卡IP地址 2.黑客对URL的哪一个参数实施了SQL注入 3.第一个受害主机网站数据库的表前缀(加上下划线例如abc) 4.…

2024毕业设计选题指南【附选题大全】

title: 毕业设计选题指南 - 如何选择合适的毕业设计题目 date: 2023-08-29 categories: 毕业设计 tags: 选题指南, 毕业设计, 毕业论文, 毕业项目 - 如何选择合适的毕业设计题目 当我们站在大学生活的十字路口,毕业设计便成了我们面临的一项重要使命。这不仅是对我们…

文本编辑器Vim常用操作和技巧

文章目录 1. Vim常用操作1.1 Vim简介1.2 Vim工作模式1.3 插入命令1.4 定位命令1.5 删除命令1.6 复制和剪切命令1.7 替换和取消命令1.8 搜索和搜索替换命令1.9 保存和退出命令 2. Vim使用技巧 1. Vim常用操作 1.1 Vim简介 Vim是一个功能强大的全屏幕文本编辑器,是L…

计算机竞赛 基于机器视觉的手势检测和识别算法

0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的手势检测与识别算法 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng…

今天学了二叉树的前序,中序和后序遍历oier

同时了解一些趣图笑死我了 所以想入门先入坟,这是最好的礼物。 废话说多了,谈谈正事,我们了解到二叉树有节点和边权;分为有向和无向图;这里如果我们需要搜索一下每一个节点的情况,所以就需要这个遍历了 1…

前端vue2、vue3去掉url路由“ # ”号——nginx配置

文章目录 ⭐前言⭐vue2中router默认出现#号💖在vue2项目中去掉💖在vue3项目中去掉 ⭐vue打包 assetsPublicPath base 为绝对路径 /💖vue2 配置 assetsPublicPath💖vue3 配置 base💖验证 ⭐nginx 配置💖 使用…

Leetcode Top 100 Liked Questions(序号105~139)

105. Construct Binary Tree from Preorder and Inorder Traversal105. Construct Binary Tree from Preorder and Inorder Traversal 题意:根据前序遍历和中序遍历来构造二叉树 我的思路 要用递归造树,要同时递归左子树和右子树,造树需要…

C语言每日一练-----Day(4)

本专栏为c语言练习专栏,适合刚刚学完c语言的初学者。本专栏每天会不定时更新,通过每天练习,进一步对c语言的重难点知识进行更深入的学习。 今日练习题关键字:记负均正    旋转数组的最小数字    二分查找 💓博主…

剑指offer(C++)-JZ29:顺时针打印矩阵(算法-模拟)

作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,…