1 freebsd网卡驱动程序详解

/* 注释:xIE_minix */
/*此处为BSD申明,略过... 最好是拷贝下来用C的开发工具来看比较好 :) */
/*
当网络上一台计算机准备发送数据时,他的网卡开始工作了,首先网卡的芯片侦听在网络上是否有数据在
流动,如果没有,他就把数据发送到网络上,在侦听和发送之间有一段极小的时间延迟,在这段时间内,也有
可能在网络上有其他的计算机也准备发送数据,也侦听到网络上没有数据在流动,这就可能两台甚至多台
的数据一起发送到网络上,产生数据的碰撞,发送数据的计算机的网卡芯片当然要在发送完成后再校验返回
的数据,如果发现和发送的数据不一致,那就是说产生了碰撞,所以在一个以太网络中的计算机数量不宜过多,
他不但会增加广播包在网络中的数量,也请也会增加数据包的碰撞次数.
我们的计算机的网卡芯片在接收到一完整的数据包后,芯片的一引脚通知8259中断控制器,中断控制器再
发出中断给CPU,由此,CPU随即调用该网卡的中断例程,如:
Dos是这样的
屏蔽所有中断(cli)
push any register
因为中断向量在段0
所以xor ax,ax
mov ds,ax
mul ax,中断号
那么在数据段的[ax]偏移处是该中断例程的指针了
call [ax]就到该中断例程了
...(DOS是比较遥远的事情了,我所描述的是他的原理,当然不会这么简单,如果那位网友有兴趣详细描述一下
上面的原理,纠正或替换掉我所写的就感激不尽了)

总之,在本例程中,CPU将调用elintr中断例程,并带有参数unit即该种网卡的第几块(因为在计算机中,你有可能
装了相同的网卡有几块),elintr的作用是把数据从网卡的数据存储器中读到我们在该网卡初始化时预先分配好
的数据缓冲区中,他调用的函数就只有elread,同样elread也只调用了elget一个函数.elread函数比较简单,就是
调用elget,elget则相对比较复杂一点,涉及到核心内存分配mbuf,mbuf是比较恐怖的东西,正如STEVEN所写的,为
了节约当时"巨大"的4M内存,牺牲了性能搞出了这个mbuf东东,mbuf是必须要弄懂的,虽然在设备驱动程序中调用
他的宏和函数不多,但在后面的IP协议,TCP协议中有不少涉及的地方.
关于数据发送方面和接收差不多,在上层协议放置好数据到mbuf链后,调用el_start函数,该函数把mbuf链中
的数据放置到本块网卡的发送队列缓冲el_pktbuf中,然后再调用el_xmit函数,此函数把发送队列缓冲el_pktbuf
中的数据有传递到网卡的数据存储器中.我认为,这中间的内存拷贝是多于的,应该在el_start函数中直接把mbuf
中的数据传递到网卡的数据存储器中,这样会使性能有较大幅度的提升,因为在驱动程序设计时,最好减少大量的
内存拷贝,他占用的时间太多了.
*/

/* FreeBSD的3COM以太网设备驱动程序 */
/*本段头文件是在编译核心时产生的*/



#include "el.h" /*此三文件为编译时产生的头文件,内容是定制核心的一些常量*/
#include "opt_inet.h"
#include "opt_ipx.h"

#include
#include
#include
#include
#include
#include

#include
#include

#include
#include

#include

#include

#include
#include /*此头文件是3COM卡的寄存器常量*/

/* 为了调试方便 */
#ifdef EL_DEBUG
#define dprintf(x) printf x /*如果定义了DEBUG调试,则打印到屏幕*/
#else
#define dprintf(x)
#endif

/* softc结构,每种网卡的该结构是不同的,主要是该第一个成员必须是一以太网的共用结构arpcom*/
static struct el_softc {
struct arpcom arpcom; /* 以太网公共部分 */
u_short el_base; /* 基本输入输出地址 */
char el_pktbuf[EL_BUFSIZ]; /* 帧缓冲大小2048 */

推荐阅读