XV6学习(16)Lab net: Network stack
最后一个实验了,代码在Github上。
这一个实验其实挺简单的,就是要实现网卡的e1000_transmit和e1000_recv函数。不过看以前的实验好像还要实现上层socket相关的代码,今年就只有网卡驱动了。
虽然实验文档里面给了一本400多页的网卡文档,但其实也不需要怎么读这本厚厚的文档,实验的hints里面就讲的挺清楚了。
实验
首先是e1000_transmit函数,按照hints一步步来就行了,唯一一个要查文档的就是cmd域,但其实这个域的宏定义里面就只给了E1000_TXD_CMD_R和E1000_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的更多相关文章
- xv6学习笔记(5) : 锁与管道与多cpu
xv6学习笔记(5) : 锁与管道与多cpu 1. xv6锁结构 1. xv6操作系统要求在内核临界区操作时中断必须关闭. 如果此时中断开启,那么可能会出现以下死锁情况: 进程A在内核态运行并拿下了p ...
- Contiki Network Stack
一.协议栈 主要有两大网络协议栈,uIP和Rime这两大协议栈(network stack): The uIP TCP/IP stack, which provides us with IPv4 ne ...
- 深度强化学习(DQN-Deep Q Network)之应用-Flappy Bird
深度强化学习(DQN-Deep Q Network)之应用-Flappy Bird 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-fu ...
- XV6学习笔记(1) : 启动与加载
XV6学习笔记(1) 1. 启动与加载 首先我们先来分析pc的启动.其实这个都是老生常谈了,但是还是很重要的(也不知道面试官考不考这玩意), 1. 启动的第一件事-bios 首先启动的第一件事就是运行 ...
- xv6学习笔记(3):中断处理和系统调用
xv6学习笔记(3):中断处理和系统调用 1. tvinit函数 这个函数位于main函数内 表明了就是设置idt表 void tvinit(void) { int i; for(i = 0; i & ...
- xv6学习笔记(4) : 进程调度
xv6学习笔记(4) : 进程 xv6所有程序都是单进程.单线程程序.要明白这个概念才好继续往下看 1. XV6中进程相关的数据结构 在XV6中,与进程有关的数据结构如下 // Per-process ...
- XV6学习笔记(2) :内存管理
XV6学习笔记(2) :内存管理 在学习笔记1中,完成了对于pc启动和加载的过程.目前已经可以开始在c语言代码中运行了,而当前已经开启了分页模式,不过是两个4mb的大的内存页,而没有开启小的内存页.接 ...
- Queueing in the Linux Network Stack !!!!!!!!!!!!!!!
https://www.coverfire.com/articles/queueing-in-the-linux-network-stack/ Queueing in the Linux Networ ...
- 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 ...
随机推荐
- 【Oracle】生成随机数
Oracle生成随机数: dbms_random.string(opt, 6) --括号里的opt要从下面的列表中选择,数字代表要生成几位随机数,如果是1位的话,就改成1 以此类推 opt可取 ...
- Xctf攻防世界—crypto—Normal_RSA
下载压缩包后打开,看到两个文件flag.enc和pubkey.pem,根据文件名我们知道应该是密文及公钥 这里我们使用一款工具进行解密 工具链接:https://github.com/3summer/ ...
- 创建Django REST framework工程
1.创建工程虚拟环境 2.创建工程目录和调整目录结构: 创建Django的项目 创建docs 用于存放一些说明文档资料 创建scripts 用于存放管理脚本文件 创建logs 用于存在日志 在与项目同 ...
- EL&Filter&Listener:EL表达式和JSTL,Servlet规范中的过滤器,Servlet规范中的监听器,观察着设计模式,监听器的使用,综合案例学生管理系统
EL&Filter&Listener-授课 1 EL表达式和JSTL 1.1 EL表达式 1.1.1 EL表达式介绍 *** EL(Expression Language):表达式语言 ...
- 《awk中文手册》-本人参考官方手册翻译
01. 简介 AWK是一个文本(面向行和列)处理工具,同时它也是一门脚本语言. AWK其名称得自于它的创始人 Alfred Aho .Peter Weinberger 和 Brian Kernigha ...
- 将汉字取模软件中的汉字放到keil5中显示
最近因为要使用STM32做毕业设计,需要用LCD显示中文,STM32开发板用的是原子的战舰STM32开发板,给的LCD显示例程里貌似没有中文显示,那么需要自己去编写中文显示程序. 软件编写对我来说并不 ...
- Spring Security,没有看起来那么复杂(附源码)
权限管理是每个项目必备的功能,只是各自要求的复杂程度不同,简单的项目可能一个 Filter 或 Interceptor 就解决了,复杂一点的就可能会引入安全框架,如 Shiro, Spring Sec ...
- JavaScript中函数的定义!
JavaScript中函数的定义! 1 自定义函数(命名函数) function fun() {}; 2 函数表达式(匿名函数) var fun = function () {}; 3 利用 new ...
- 在Sublime Text 2工具下编辑laravel框架
介绍Sublime编辑器 Sublime Text 3官方版是Sublime Text2的升级版.Sublime Text是一款流行的文本编辑器软件,有点类似于TextMate,跨平台,可运行在Lin ...
- Compile-time Dependency Injection With Go Cloud's Wire 编译时依赖注入 运行时依赖注入
Compile-time Dependency Injection With Go Cloud's Wire - The Go Blog https://blog.golang.org/wire Co ...