Lab7 networking
https://pdos.csail.mit.edu/6.828/2023/labs/net.html
背景
为E1000实现驱动,补全kernel/e1000.c中的两个空函数。
为了达成目的,需要看E1000的文档,对E1000有足够的了解。
驱动程序
驱动程序分为top、bottom两部分:
- top:运行内核线程,由系统调用(例如read、write)调用,要求设备执行IO(发包)。
- bottom:中断处理线程,硬件中断(例如网卡收到包)调用,处理中断(收包)。
本实验中,top部分的调用链示例:

E1000手册
接收描述符
网卡约定的数据格式。当收到一个数据包时,网卡填充的信息。

与之对应的代码是:

发送描述符

代码中与之对应的数据结构是tx_desc。
寄存器约定
手册中约定了控制寄存器的地址,例如环形队列的地址…:

与之对应的宏定义在kernel/e1000_dev.h中
举例:
- 硬件约定好了,0x02810位置存储了接收描述符环形队列的队首指针。
- 内核初始化时,将接收描述符环形队列的队首指针写入0x02810
- 此时,当硬件收到包时,会构建一个描述符,放在0x02810中存储的指针指向的环形队列队首,并产生一个中断。
环形队列
以接收环形队列为例:
为硬件所有,当网卡收到包时,会检查环形队列 head 位置的描述符。然后把数据写入 head 描述符的缓冲区。

接收功能的初始化代码,初始化了环形队列rx_ring;对应的mbuf;位于指定内存中的控制寄存器regs:

所以,接收函数就是要去实现处理这个环形队列中已有的待处理包。
此时,生产者是硬件网卡(维护head指针),消费者是需要实现的接收函数(维护tail指针)。
生产者消费者之间的通讯方式是:网卡收到包时产生中断,中断处理程序去调用接收函数。
代码实现
发送
作为生产者将入参mbuf打包发送到发送环形队列中,这样硬件作为消费者会自己处理(发出去)。
int e1000_transmit(struct mbuf *m) {
//
// Your code here.
//

本文介绍了如何补全Linux内核中的E1000网络驱动程序,涉及接收描述符、发送描述符、环形队列的使用以及中断处理。实验涉及发送函数inte1000_transmit和接收函数e1000_recv的代码实现及可能遇到的问题.
最低0.47元/天 解锁文章
1405

被折叠的 条评论
为什么被折叠?



