本实验开发一个网卡驱动程序,其相关代码分布如下:
任务:实现e1000_transmit和e1000_recv,使得网络驱动能够发送和接收数据包。
细节:
实现效果:
本实验的实现需要了解xv6系统的网络协议及其实现,可以参考:xv6源码分析--networking
int
e1000_transmit(struct mbuf *m)
{
acquire(&e1000_lock);
uint32 bufindex=regs[E1000_TDT];
struct tx_desc *desc=&tx_ring[bufindex];
//该packet已经发送完了
if(!(desc->status&E1000_TXD_STAT_DD)){
release(&e1000_lock);
return -1;
}
//如果该mbuf还未释放,则释放掉
if(tx_mbufs[bufindex]){
mbuffree(tx_mbufs[bufindex]);
tx_mbufs[bufindex]=0;
}
desc->addr=(uint64)m->head;
desc->length=m->len;
//该packet是完整的
desc->cmd=E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS;
tx_mbufs[bufindex]=m;
regs[E1000_TDT]=(regs[E1000_TDT]+1)%TX_RING_SIZE;
release(&e1000_lock);
return 0;
}
static void
e1000_recv(void)
{
while(1){
uint32 bufindex=(regs[E1000_RDT]+1)%RX_RING_SIZE;
struct rx_desc * desc=&rx_ring[bufindex];
if(!(desc->status & E1000_RXD_STAT_DD))
return;
rx_mbufs[bufindex]->len=desc->length;
//数据由设备写入到内存中,不经过CPU,直接调用协议栈处理即可
net_rx(rx_mbufs[bufindex]);
rx_mbufs[bufindex]=mbufalloc(0);
desc->addr=(uint64)rx_mbufs[bufindex]->head;
desc->status=0;
regs[E1000_RDT]=bufindex;
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。