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循环,把能读的数据包都读出来。我猜是因为一次中断不一定代表只有一个数据包到了,甚至在处理中断的过程中,还会有数据包到。如果每次中断只读一个,会导致丢很多包

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JVM 之字节码(.class)文件

本文中的内容参考B站尚硅谷宋红康JVM全套教程 你将获得: 1、掌握字节码文件的结构 2、掌握Java源代码如何在JVM中执行 3、掌握一些虚拟机指令 4、回答一些面试题 课程介绍 通过几个面试题初始字节码文件为什么学习class字节码文件什么是class字节码文件分析c…

做区块链卡牌游戏有什么好处?

区块链卡牌游戏是一种基于区块链技术的创新性游戏形式,它将传统的卡牌游戏与区块链技术相结合,实现了去中心化、数字化资产的交易和收集。这种新型游戏形式正逐渐在游戏行业引起了广泛的关注和热潮。本文将深入探讨区块链卡牌游戏的定义、特点以及其在未…

App与小程序工具总结

文章目录 前言Burpsuite抓包问题LPosedJustTrustMe 绕过 SSL Pining小程序的反编译APP脱壳,反射大师、frida反射大师Frida 总结 前言 在进行渗透工作的时候,遇到过的App、小程序也不少了,有简单的,也有加固的比较不错的&#xff…

Servlet与过滤器

目录 Servlet 过滤器 Servlet Servlet做了什么 本身不做任何业务处理,只是接收请求并决定调用哪个JavaBean去处理请求,确定用哪个页面来显示处理返回的数据 Servlet是什么 ServerApplet,是一种服务器端的Java应用程序 只有当一个服务器端的程序使用了Servlet…

Ansible学习笔记12

playbook: playbook(剧本):是ansible用于配置、部署和管理被控节点的剧本,用于Ansible操作的编排。 使用的是yaml格式,(saltstack、elk、docker、docker-compose、k8s都会使用到yaml格式。&am…

【数据结构】| 并查集及其优化实现

目录 一. 并查集基本概念处理过程初始化合并查询小结 二. 求并优化2.1 按大小求并2.2 按秩(高度)求并2.3 路径压缩2.4 类的实现代码2.5 复杂度分析 三. 应用LeetCode 128: 最长连续数列LeetCode 547: 省份数量LeetCode 200: 岛屿数量 一. 并查集基本概念 以一个直观的问题来引入…

vue3的hooks你可以了解一下

更详细的hooks了解参考这个大佬的文章:掘金:Hooks和Mixins之间的区别 刚开始我简单看了几篇文章感觉Hooks这个东西很普通,甚至感觉还不如vue2的mixin好用。还有export import 感觉和普通定义一个utils文件使用没什么区别。但是Hooks这个东西肯…

kotlin实现猜数游戏

游戏规则 1.程序随机生成一个1到100的数字,作为MagicNumber 2.用户根据提示输入数据,只有三次机会输入数据 代码 代码很简单,使用了let内置函数 fun main() {//生成随机数可以使用java的方法//val magicNumber Random().nextInt(11)val ma…

设计模式--迭代器模式(Iterator Pattern)

一、什么是迭代器模式 迭代器模式(Iterator Pattern)是一种行为型设计模式,用于提供一种统一的方式来访问一个聚合对象中的各个元素,而不需要暴露该聚合对象的内部结构。迭代器模式将遍历集合的责任从集合对象中分离出来&#xf…

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

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

【计算机组成 课程笔记】2.1 设计自己的计算机

课程链接: 计算机组成_北京大学_中国大学MOOC(慕课) 2 - 1 - 201-设计自己的计算机(14‘24’‘)_哔哩哔哩_bilibili 什么是指令系统体系结构?这个问题其实非常简单,但要想解释清楚也没有那么容易。我们还是从一个小故事…

【算法训练-数组 三】数组中的第K个最大元素(TOPK问题|寻找第K大)

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【寻找第K大】,使用【数组】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为&…

设计模式--代理模式(Proxy Pattern)

一、什么是代理模式(Proxy Pattern) 代理模式(Proxy Pattern)是一种结构型设计模式,它允许一个对象(代理)充当另一个对象(真实对象)的接口,以控制对该对象的…

HCIP-HCS华为私有云的使用

1、概述 华为公有云(HC)、华为私有云(HCS)华为混合云(HCSO)。6.3 之前叫FusionSphere OpenStack,6.3.1 版本开始叫FusionCloud,6.5.1 版本开始叫Huawei Cloud Stack (HCS)华为私有云…

前端调用电脑摄像头

项目中需要前端调用,所以做了如下操作 先看一下效果吧 主要是基于vue3,通过canvas把画面转成base64的形式,然后是把base64转成 file文件,最后调用了一下上传接口 以下是代码 进入页面先调用一下摄像头 navigator.mediaDevices.ge…

无涯教程-Android - List View函数

Android ListView 是垂直滚动列表中显示的视图,使用 Adapter 从列表(如数组或数据库)中获取内容的列表项会自动插入列表中。 适配器(Adapter)实际上是UI组件和将数据填充到UI组件中的数据源之间的桥梁,适配器保存数据并将数据发送到适配器视图&#xff0…

基于猎食者算法优化的BP神经网络(预测应用) - 附代码

基于猎食者算法优化的BP神经网络(预测应用) - 附代码 文章目录 基于猎食者算法优化的BP神经网络(预测应用) - 附代码1.数据介绍2.猎食者优化BP神经网络2.1 BP神经网络参数设置2.2 猎食者算法应用 4.测试结果:5.Matlab代…

认识SQL sever

目录 一、数据库的概念 1.1数据库的基本概念 1.2对数据库的了解 二、数据库的分类 2.1关系型数据库(RDBMS): 2.2非关系型数据库(NoSQL): 2.3混合数据库: 2.4数据仓库: 2.5嵌…

静态路由(详细理解+实例精讲)

系列文章目录 华为数通学习(6) 前言 一,静态路由 二,静态路由配置 三,缺省路由 四,缺省路由应用场景 总结 前言 随着华为公司的不断发展,数据通信这门技术也越来越重要,很多人…

PyQt6 GUI界面设计和Nuitka包生成exe程序(全笔记)

PyQt6 GUI界面设计和Nuitka包,生成exe程序全笔记 目录一、PyQt6包安装1.1 进行环境配置和安装1.2 检查包是否安装成功。1.3 运行desinger.exe二、GUI界面设计,写程序,并能运行成功。三、Nuitka打包生成exe程序3.1 做Nuitka安装准备工作(1)安装C编译器,设置环境变量3.2 安…