最后一个实验了,代码在Github上。

这一个实验其实挺简单的,就是要实现网卡的e1000_transmite1000_recv函数。不过看以前的实验好像还要实现上层socket相关的代码,今年就只有网卡驱动了。

虽然实验文档里面给了一本400多页的网卡文档,但其实也不需要怎么读这本厚厚的文档,实验的hints里面就讲的挺清楚了。

实验

首先是e1000_transmit函数,按照hints一步步来就行了,唯一一个要查文档的就是cmd域,但其实这个域的宏定义里面就只给了E1000_TXD_CMD_RE1000_TXD_CMD_EOP这两个,也就是说我们只要关注这两个就行了:

int
e1000_transmit(struct mbuf *m)
{
acquire(&e1000_lock); uint32 idx = regs[E1000_TDT];
struct tx_desc* desc = &tx_ring[idx]; if((desc->status & E1000_TXD_STAT_DD) == 0){
release(&e1000_lock);
printf("buffer overflow\n");
return -1;
} if(tx_mbufs[idx])
mbuffree(tx_mbufs[idx]); desc->addr = (uint64)m->head;
desc->length = m->len;
desc->cmd = E1000_TXD_CMD_RS | E1000_TXD_CMD_EOP;
tx_mbufs[idx] = m; regs[E1000_TDT] = (idx + 1) % TX_RING_SIZE;
__sync_synchronize();
release(&e1000_lock);
return 0;
}

然后是e1000_recv函数,这里注意一次中断应该把所有到达的数据都处理掉,剩下的按hints里面的来就行了:

static void
e1000_recv(void)
{
int idx = (regs[E1000_RDT] + 1) % RX_RING_SIZE;
struct rx_desc* desc = &rx_ring[idx]; while(desc->status & E1000_RXD_STAT_DD){
acquire(&e1000_lock); struct mbuf *buf = rx_mbufs[idx];
mbufput(buf, desc->length); rx_mbufs[idx] = mbufalloc(0);
if (!rx_mbufs[idx])
panic("mbuf alloc failed");
desc->addr = (uint64) rx_mbufs[idx]->head;
desc->status = 0; regs[E1000_RDT] = idx;
__sync_synchronize();
release(&e1000_lock); net_rx(buf); idx = (regs[E1000_RDT] + 1) % RX_RING_SIZE;
desc = &rx_ring[idx];
}
}

总结

到这里整个XV6的实验就完成了,赶在了过年之前写完了。不得不说国外的实验设计的真的好,实验的代码量都不大,每个实验就是几个函数,实验的难度也设置的很合适。十一个实验做完,配套讲义看完之后就把XV6内核的绝大部分内容都看完了,对于操作系统的核心部分也都通过实验有了更加深入的了解。知道了线程和进程切换之间的区别以及上下文切换是如何进行的;从以前只直到页表这个概念到现在知道了整个分页机构是如何运行的,亲手实现了基于分页和缺页异常的COW fork,mmap,lazy allocation等技术;知道了系统调用是如何实现的以及操作系统是如何与硬件配合来对系统调用和中断陷阱进行处理。

总而言之,强烈推荐学完了操作系统系统通过这个课程的实验来加深和巩固理解,而不是只停留在课本的那些概念上,一点实际的内核代码都没有接触过。XV6内核的实现非常精简,但是所有核心功能都实现了,而且编译速度快,也不需要很多的配置,相比于Linux内核更加适合初学者来学习,在讲义中也介绍了很多相比于Linux的可以改进的地方。

XV6学习(16)Lab net: Network stack的更多相关文章

  1. xv6学习笔记(5) : 锁与管道与多cpu

    xv6学习笔记(5) : 锁与管道与多cpu 1. xv6锁结构 1. xv6操作系统要求在内核临界区操作时中断必须关闭. 如果此时中断开启,那么可能会出现以下死锁情况: 进程A在内核态运行并拿下了p ...

  2. Contiki Network Stack

    一.协议栈 主要有两大网络协议栈,uIP和Rime这两大协议栈(network stack): The uIP TCP/IP stack, which provides us with IPv4 ne ...

  3. 深度强化学习(DQN-Deep Q Network)之应用-Flappy Bird

    深度强化学习(DQN-Deep Q Network)之应用-Flappy Bird 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-fu ...

  4. XV6学习笔记(1) : 启动与加载

    XV6学习笔记(1) 1. 启动与加载 首先我们先来分析pc的启动.其实这个都是老生常谈了,但是还是很重要的(也不知道面试官考不考这玩意), 1. 启动的第一件事-bios 首先启动的第一件事就是运行 ...

  5. xv6学习笔记(3):中断处理和系统调用

    xv6学习笔记(3):中断处理和系统调用 1. tvinit函数 这个函数位于main函数内 表明了就是设置idt表 void tvinit(void) { int i; for(i = 0; i & ...

  6. xv6学习笔记(4) : 进程调度

    xv6学习笔记(4) : 进程 xv6所有程序都是单进程.单线程程序.要明白这个概念才好继续往下看 1. XV6中进程相关的数据结构 在XV6中,与进程有关的数据结构如下 // Per-process ...

  7. XV6学习笔记(2) :内存管理

    XV6学习笔记(2) :内存管理 在学习笔记1中,完成了对于pc启动和加载的过程.目前已经可以开始在c语言代码中运行了,而当前已经开启了分页模式,不过是两个4mb的大的内存页,而没有开启小的内存页.接 ...

  8. Queueing in the Linux Network Stack !!!!!!!!!!!!!!!

    https://www.coverfire.com/articles/queueing-in-the-linux-network-stack/ Queueing in the Linux Networ ...

  9. RH253读书笔记(5)-Lab 5 Network File Sharing Services

    Lab 5 Network File Sharing Services Goal: Share file or printer resources with FTP, NFS and Samba Se ...

随机推荐

  1. 【函数分享】每日PHP函数分享(2021-1-19)

    substr 函数返回字符串的一部分.注释:如果 start 参数是负数且 length 小于或等于 start,则 length 为 0. string substr (string $string ...

  2. Linux Shell 编程基础详解——吐血整理,墙裂推荐!

    第一部分:Linux Shell 简介 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言. Shell 是指一种应用程序, ...

  3. Job for docker.service failed because start of the service was attempted too often. See "systemctl status docker.service" and "journalctl -xe" for details. To force a start use "systemctl reset-failed

    安装docker时,自己添加了国内的hub.docker.com镜像 [root@ce-docker ~]# systemctl restart docker 出现以下报错:Job for docke ...

  4. SQL Server management studio使用sa连接时报错与伺服器的连接已成功,但在登入程序是发生错误

    使用Sql Server management studio的sa用户连接数据库时,报如下错误 解决方法: 1.使用windows验证登录 2.右键点击连接,点击属性,点击安全性,选择混合验证 3.重 ...

  5. SAP 修改数据元素 注意事项

    在修改数据元素的时候,通常要注意一下几点: 1.在修改完数据元素后,如果激活不成功,那么就要通过SE14进入数据库实用程序,在对象名处输入数据元素相关联的表的名称 下面词典对象选择表,然后点击编辑,处 ...

  6. pandas DataFrame的新增行列,修改、删除、筛选、判断元素以及转置操作

    1)指定行索引和列索引标签 index 属性可以指定 DataFrame 结构中的索引数组,  columns 属性可以指定包含列名称的行, 而使用 name 属性,通过对一个 DataFrame 实 ...

  7. uni-app开发经验分享九: 组件传值

    一.父组件向子组件传值 通过props来实现,子组件通过props来接收父组件传过来的值! 1.逻辑梳理 父组件中: 第一步:引入子组件: import sonShow from '../../com ...

  8. [APUE] 进程环境

    APUE 一书的第七章学习笔记. 进程终止 有 8 种方式可以使得进程终止,5 种为正常方式: Return from main Calling exit() Calling _exit or _Ex ...

  9. 【python刷题】LRU

    什么是LRU? LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰.该算法赋予每个页面一个访问字段,用来记录一个页面自上次 ...

  10. CI/CD 最佳实践的基本原则 互联网后端架构 2020-10-04

    https://mp.weixin.qq.com/s/UfGmCueEm8n2jdegng1F_g CI/CD 最佳实践的基本原则 互联网后端架构 2020-10-04