------------------- ---------------------
| | / \
\ / | |
-------------------------------------------------------
| methods and variables(initialize,open,close,hard_xmit,|
| interrupt handler,config,resources,status...) |
-------------------------------------------------------
| | / \
\ / | |
----------------- ----------------------
|send to hardware | |receivce from hardware|
----------------- ----------------------
| | / \
\ / | |
-----------------------------------------------------
| hardware media |
-----------------------------------------------------
初始化程式完成硬件的初始化、device中变量的初始化和系统资源的申请。发送
程式是在驱动程式的上层协议层有数据要发送时自动调用的。一般驱动程式中不对发
送数据进行缓存,而是直接使用硬件的发送功能把数据发送出去。接收数据一般是通
过硬件中断来通知的。在中断处理程式里,把硬件帧信息填入一个skbuff结构中,然
------------------ Linux操作系统网络驱动程式编写 -------------------
------------ Contact the author by mailto:bordi@bordi.dhs.org ------
后调用netif_rx()传递给上层处理。
2.2 网络驱动程式的基本方法
网络设备做为一个对象,提供一些方法供系统访问。正是这些有统一接口的方法,
掩蔽了硬件的具体细节,让系统对各种网络设备的访问都采用统一的形式,做到硬件
无关性。
下面解释最基本的方法。
2.2.1 初始化(initialize)
驱动程式必须有一个初始化方法。在把驱动程式载入系统的时候会调用这个初
始化程式。他做以下几方面的工作。检测设备。在初始化程式里您能够根据硬件的
特征检查硬件是否存在,然后决定是否启动这个驱动程式。配置和初始化硬件。在
初始化程式里您能够完成对硬件资源的配置,比如即插即用的硬件就能够在这个时
候进行配置(Linux内核对PnP功能没有很好的支持,能够在驱动程式里完成这个功
能)。配置或协商好硬件占用的资源以后,就能够向系统申请这些资源。有些资源是
能够和别的设备共享的,如中断。有些是不能共享的,如IO、DMA。接下来您要初始
化device结构中的变量。最后,您能够让硬件正式开始工作。
2.2.2 打开(open)
open这个方法在网络设备驱动程式里是网络设备被激活的时候被调用(即设备状
态由down-->up)。所以实际上很多在initialize中的工作能够放到这里来做。比如资
源的申请,硬件的激活。假如dev->open返回非0(error),则硬件的状态还是down。
open方法另一个作用是假如驱动程式做为一个模块被装入,则要防止模块卸载时
设备处于打开状态。在open方法里要调用MOD_INC_USE_COUNT宏。
2.2.3 关闭(stop)
close方法做和open相反的工作。能够释放某些资源以减少系统负担。close是在
设备状态由up转为down时被调用的。另外假如是做为模块装入的驱动程式,close里
应该调用MOD_DEC_USE_COUNT,减少设备被引用的次数,以使驱动程式能够被卸载。
另外close方法必须返回成功(0==success)。
2.2.4 发送(hard_start_xmit)
任何的网络设备驱动程式都必须有这个发送方法。在系统调用驱动程式的xmit
时,发送的数据放在一个sk_buff结构中。一般的驱动程式把数据传给硬件发出去。
也有一些特别的设备比如loopback把数据组成一个接收数据再回送给系统,或
dummy设备直接丢弃数据。
假如发送成功,hard_start_xmit方法里释放sk_buff,返回0(发送成功)。假如
设备暂时无法处理,比如硬件忙,则返回1。这时假如dev->tbusy置为非0,则系统
认为硬件忙,要等到dev->tbusy置0以后才会再次发送。tbusy的置0任务一般由中断
完成。硬件在发送结束后产生中断,这时能够把tbusy置0,然后用mark_bh()调用通
知系统能够再次发送。在发送不成功的情况下,也能够不置dev->tbusy为非0,这样
系统会不断尝试重发。假如hard_start_xmit发送不成功,则不要释放sk_buff。
传送下来的sk_buff中的数据已包含硬件需要的帧头。所以在发送方法里不需
要再填充硬件帧头,数据能够直接提交给硬件发送。sk_buff是被锁住的(locked),
确保其他程式不会存取他。
2.2.5 接收(reception)
驱动程式并不存在一个接收方法。有数据收到应该是驱动程式来通知系统的。
一般设备收到数据后都会产生一个中断,在中断处理程式中驱动程式申请一块
sk_buff(skb),从硬件读出数据放置到申请好的缓冲区里。接下来填充sk_buff中
的一些信息。skb->dev = dev,判断收到帧的协议类型,填入skb->protocol(多协
议的支持)。把指针skb->mac.raw指向硬件数据然后丢弃硬件帧头(skb_pull)。还要
配置skb->pkt_type,标明第二层(链路层)数据类型。能够是以下类型:
PACKET_BROADCAST : 链路层广播
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




