一、概述
Linux網路裝置驅動程式遵循通用的介面,設計時採用的是物件導向的方法,一個裝置就是一個對象(net_device結構)。一個網路裝置最基本的方法有初始化、發送和接收等。
Linux網路裝置驅動程式的體繫結構可以分為四層:網路通訊協定介面層、網路裝置介面層、裝置驅動功能層和網路裝置與媒介層,1所示。網路裝置驅動程式最主要的工作是完成裝置驅動功能層。在Linux中,所有網路裝置都抽象為一個介面,這個介面提供了對所有網路裝置的操作集合。由資料結構struct net_device來表示網路裝置在核心中的運行情況,即網路裝置介面。它既包括純軟體網路裝置介面,如環路(loopback),也包括硬體網路裝置介面,如乙太網路卡。由以dev_base為頭指標的裝置鏈來集體管理所有網路裝置,該裝置鏈中的每個元素代表一個網路裝置介面。資料結構net_device中有很多供系統訪問和協議層調用的裝置方法,包括初始化,開啟和關閉網路裝置的open和stop函數,處理資料包發送的hard_start_xmit函數,以及中斷處理函數等。
圖1 網路裝置驅動體繫結構
二、資料包發送流程
當網路子系統上層有資料包要發送時,通過調用網路裝置驅動中的實現的ndo_start_xmit函數,將要發送的資料包封裝在通訊端緩衝區skb參數中。在驅動程式的發送資料包函數的具體實現中,它將首先在skb資料包所在主存中的資料區塊和網路裝置記憶體之間建立一個DMA通道,然後啟動該DMA通道將資料包由主存傳輸到裝置記憶體,之後由網路裝置硬體通過網路介面或者天線將資料包發送出去。資料包發送成功後會向處理器發出一個硬體中斷,在中斷處理常式裡做一些善後處理工作,2所示。
圖2 網路裝置驅動程式資料包發送流程
三、資料包接收流程
資料包的接收是一個非同步過程,正因為這樣,出於系統效能的考慮,絕大部分網路裝置都支援資料接收中斷,因此在驅動程式中是通過中斷處理常式來接收資料包的。由於系統主存與網路裝置之間已經建立好DMA通道,所有當有資料包到達網路裝置時,資料包會被自動傳輸到系統主存,此時將產生一個中斷訊號,從而進入驅動程式的中斷處理函數,在中斷處理函數裡驅動首先會分配一個通訊端緩衝區skb來容納收到的資料包,然後將skb傳遞到網路子系統的上層代碼中,具體傳遞的過程是驅動程式通過調用netif_rx(skb)函數實現的,上層代碼負責釋放該skb所佔用的記憶體,3所示。
圖3 網路裝置驅動資料包接收流程