分析skb和网卡驱动的关系 | |
| |
来源: ChinaUnix博客 日期: 2007.09.23 11:14 (共有条评论) 我要评论 | |
分析skb和网卡驱动的关系 by good02xaut 网卡驱动所能看到的仅仅是MAC帧,MAC帧独立于任何上层协议,仅仅属于数据链路层。 以太网为例,DM9000作为设备。 1.发送的skb是什么样?(内核决定) 发送的MAC帧格式: PR| SD | DA |SA |TYPE | IP packet | FCS 红色的内容,是驱动程序需要提供的MAC帧内容,黑色的部分由DM9000网卡自动填充进去。 DM9000的发送函数: dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) skb->data的缓冲区内容正是:00 00 | DA |SA |TYPE | IP packet | 因此,只需将skb->data内容拷贝到DM9000的发送缓冲区即可。DM9000构造出完整的 PR| SD | DA |SA |TYPE | IP packet | FCS MAC帧,发送到物理线路上。 2.接收的skb如何?(DM9000决定) DM9000从物理线路上接收到的是标准的MAC帧,和发送一致: PR| SD | DA |SA |TYPE | IP packet | FCS 然而,DM9000的接收缓冲区却没有把MAC帧全部保存进来。 DM9000接收缓冲的内容是: 01|status| byte count low | byte count high | DA |SA |TYPE | IP packet | FCS 绿色部分,是DM9000自动产生,不是从线路接收到的。后面的非绿色则是从线路接收到的。 如何从接收缓冲区构造出需要的skb呢?其实就是创建skb->data: | DA |SA |TYPE | IP packet | RxLen 的长度=| DA |SA |TYPE | IP packet | FCS dev_alloc_skb(RxLen + 4) 分配的skb空间可以保存 01|status| byte count low | byte count high | DA |SA |TYPE | IP packet | FCS 事实上多出的4字节没有保存蓝色的信息,蓝色信息对于skb没有意义。 skb_reserve(skb, 2); skb->data的前面保留2字节,为了对齐用。| DA |SA |TYPE =14 bytes IP packet是16 byte对齐的! 实际接收到的数据包有效长度RxLen - 4,即红色部分| DA |SA |TYPE | IP packet | FCS,去掉FCS的4字节 rdptr = (u8 *) skb_put(skb, RxLen - 4); 思考题: DM9000从物理线路上收到的字节数是RxLen还是RxLen-4呢? 程序中是db->stats.rx_bytes += RxLen;将FCS也包含进来。 ============================ skb = dev_alloc_skb(RxLen + 4)) != NULL)) { skb_reserve(skb, 2); rdptr = (u8 *) skb_put(skb, RxLen - 4); /* Read received packet from RX SRAM */ (db->inblk)(db->io_data, rdptr, RxLen); db->stats.rx_bytes += RxLen; /* Pass to upper layer */ skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); 最后构造的skb内存分布(蓝色部分就是skb->data,我们所需要提供给上层的) head 保留区(16字节对齐的) 长度未知 data 保留区 2字节 | DA |SA |TYPE | 14字节 IP packet 16字节对齐的 tail FCS 4字节 end 未用区 2字节 3.总结 通过前面的介绍,应该明白驱动中发送接收时使用的skb内容是什么,以及如何根据设备特性构造skb。 |
分析skb和网卡驱动的关系
最新推荐文章于 2024-07-26 15:30:28 发布