最后一个实验了,代码在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的可以改进的地方。

最新文章

  1. 解决为什么每次打开Eclipse新的workspace需要更新nexus-maven-repository-index问题
  2. PPAS Migration Toolkit document
  3. hdu3861 强连通+最小路径覆盖
  4. JS对象基础
  5. Ext 面向对象程序设计 入门篇
  6. C# double float int string 与 byte数组 相互转化
  7. 轻奢品牌全面崛起 Coach、UGG等纷纷抢滩新兴市场_新闻中心_赢商网
  8. Javascript:scrollWidth,clientWidth,offsetWidth的区别(转)
  9. [RPM,YUM]RHEL Centos mount local source / RHEL CentOS挂载本地源
  10. 导入JavaWeb 项目出现的问题
  11. 简单读!tomcat源码(一)启动与监听
  12. springboot:SunCertPathBuilderException: unable to find valid certification path to requested target
  13. Get Set的问题解决
  14. sublime开启vim模式
  15. python基本数据类型之集合
  16. linux上apache并发数与服务器内存关系计算!
  17. SQL中EXCEPT和Not in的区别?
  18. java序列化与反序列化(转)
  19. Flask 数据库迁移
  20. Load balancer does not have available server for client:xxx

热门文章

  1. [mysql]ERROR 1364 (HY000): Field 'ssl_cipher' doesn't have a default value
  2. 【ORACLE错误】SP2-0618: Cannot find the Session Identifier. Check PLUSTRACE role is enabled
  3. 图像分割论文 | DRN膨胀残差网络 | CVPR2017
  4. Spring-AOP为类增加新的功能
  5. 求得二叉搜索树的第k小的元素
  6. 琐碎的想法(三)对Java的批评的看法
  7. MySQL 压测
  8. 【LinuxShell】ps 命令浅析
  9. DDD领域驱动设计:仓储
  10. tcpdump抓包及tshark解包方法介绍