網路裝置驅動及程式實現步驟
1、網路資料封裝過層
dev_queue_xmit(struct sk_buf *skb); //上層協議傳送資料報
int netif_rx(struct sk_buf *skb); //上層協議接受資料報
struct sk_buf 套接字緩衝區,用於在linux網路子系統中各層之間傳遞資料,是linux網路子系統資料傳輸的中樞神經,
其中的關鍵成員有
1)各層協議頭
(1)、傳輸層協議頭
union h;
(2)、網路層協議頭
union nh;
(3)、鏈路層協議頭
unionmac;
2)資料快取區指標
unsigned char *head:
指向記憶體中已經分配的用於承載網路資料的緩衝區起始位址,sk_buff和相關資料塊在分配後該指標的值就被固定了。
unsigned char *data:
指向對應當前協議層有效資料的起始位址,每層協議有效資料含義不同。
unsigned char *tail:
指向當前協議層有效資料負載的結尾位址。
unsigned char *end:
指向分配的資料緩衝區的結尾,分配完即固定。
3)、長度資訊
unsigned int data_len:
記錄在frags和frag_list中網路報文的長度。
unsigend int len:
記錄網路報文的總長度。
unsigned int truesize:
記錄head所指的儲存區的大小。
struct sk_buf 套接字緩衝區相關的操作
1)、分配:
struct sk_buff *alloc_skb(unsigned int len,int priority);
分配乙個套接字緩衝區和乙個資料緩衝區,len為資料緩衝區大小,16位元組對齊。
struct sk_buff *dev_alloc_skb(unsigned int)
以gfp_atomic方式呼叫上面介面,並保留head和data之間的16個位元組。
2)釋放
void kfree_skb(struct sk_buff *skb)
核心內部使用。
void dev_kfree_skb(struct sk_buff *skb)
驅動中使用,用於非中斷上下文。
void dev_kfree_skb_irq(kfree_skb(struct sk_buff *skb)
驅動中使用,用於中斷上下文。
void dev_kfree_skb_any(kfree_skb(struct sk_buff *skb)
驅動中使用,中斷和非中斷上下文都可以。
3)、指標移動
(1)、put操作
將tail指標下移,增加sk_buff的len值,並返回skb->tail的當前值,用於在緩衝區尾部新增資料。
unsigned char *skb_put(struct sk_buff *skb,unsigned int len)
(2)、push操作
將data指標上移,增加len的值,在儲存空間的頭部增加一段可以儲存網路資料的空間,主要用於在資料報傳送時新增頭部。
unsigned char *skb_push(struct sk_buff *skb,unsigned int len)
(3)、pull操作
將data指標下移,並減小skb的len的值,一般用於下層協議向上層協議移交資料報,使data指向上一層協議的協議頭。
unsigned char *skb_pull(struct sk_buff *skb,unsigned int len)
(4)、reserve操作:
將data指標和tail指標同時下移,主要用於在儲存空間的頭部預留len長度的空隙。
unsigned char *skb_reserve(struct sk_buff *skb,unsigned int len)
2、網路驅動需要實現的功能
1)、網絡卡的初始化
2)、資料的傳送
3)、資料的接收(中斷)
4)、其它(流量控制,錯誤統計,超時處理)
3、網路驅動程式實現步驟
a、宣告net_device變數並實現相關函式
net_device *dev = alloc_etherdev(0);
實現dev的如下函式:
實現init函式,完成裝置的初始化和net_device結構體變數自身的初始化。
實現開啟裝置(open)和關閉裝置(stop)
實現傳送函式(hard_start_transmit)
實現中斷處理函式,處理中斷。
實現資料接收函式。
實現其他的函式get_stats,do_ioctl
b、註冊網路裝置的net_device變數
register_netdev(dev);
核心以dev_base為頭指標的裝置鍊錶來集體管理所有網路裝置,該裝置鍊錶中的每個元素代表乙個網路裝置介面。register_netdev把註冊的dev插入到dev_base鍊錶中。
1)、初始化
模組初始化:主要完成註冊(register_netdev)網路裝置的工作。
網路裝置初始化:既可以放在init_module函式中完成,也可由net_device資料結構中的init函式指標所指的初始化函式來完成的。工作包括:
首先檢測網路物理裝置是否存在,這是通過檢測物理裝置的硬體特徵來完成,然後再對裝置進行資源配置。
構造並初始化裝置的net_device資料結構,並把檢測到的數值來對net_device中的變數初始化,比如mac位址等。
2)、open介面
初始化硬體,準備傳送資料。
註冊中斷處理函式(可以在net_device的init函式中註冊)。
啟動介面的傳輸佇列(允許介面接受傳輸資料報)。核心提供的如下函式可啟動該佇列netif_start_queue。
3)、傳送資料報
核心要傳輸乙個資料報,會呼叫 hard_start_xmit 方法將資料放入傳送佇列。核心處理後的每個資料報位於乙個套接字緩衝區結構(struct sk_buff)裡。這個緩衝區包含了物理資料報(以它在介質上的格式),並擁有完整的傳輸層資料報頭。介面無需修改要傳輸的資料。
hard_start_xmit函式的處理過程:
得到要傳送資料的起始位址和長度。skb->data 指向要傳輸的資料報,而 skb->len 是以位元組為單位的長度。
把資料傳送到網絡卡的物理緩衝區中。可以直接把資料寫入緩衝區暫存器中;或者通過dma的方式傳送資料。
網絡卡把得到的資料傳送到物理媒介中去。這一步一般由網絡卡自動完成。
4)、接收資料報
處理接收資料報的方式:一般通過中斷方式
中斷方式:當有新資料到來時,中斷處理器操作,並呼叫中斷處理程式接收新資料。
輪詢方式:每隔一定間隔訪問網絡卡暫存器,判斷是否有新資料到來。如果有則接收資料。
兩種方式都可以。但中斷方式效率高,占用系統資源少。
5)、中斷處理程式
大多數網絡卡都可以通過中斷處理程式來控制。中斷可能產生的原因:
新資料報到達
外發資料報的傳輸已經完成
資料傳送或接收錯誤。
處理流程:
讀取中斷暫存器,判斷中斷發生的原因。
如果中斷是新資料到來,進入資料接收函式。
如果中斷是資料報傳送完成,或者產生傳輸錯誤,進行資料統計。
linux網路裝置驅動
linux網路裝置驅動 linux網路驅動程式的體系結構可劃分為4個層次。linux核心源 中提供了網路裝置介面及以網路子系統的上層的 移植特定網路硬體的驅動程式的主要工作就是完成裝置驅動功能層的相應 根據底層具體的硬體特性,定義網路裝置介面struct net device型別的結構體變數,並實現...
linux 網路裝置驅動
linux 網路驅動 謹以此文紀念過往的歲月 一.前言 在linux中網路驅動也是乙個大頭,如何去理解網路驅動是作為乙個linux驅動工程師必備的技能。不過同樣的裝置,在不同人的手中會有不同的效果,其原因就在於驅動的好與否。二.裝置註冊 學習網路的驅動與學習普通cdev驅動一樣,都是學習其模板,然後...
Linux網路裝置驅動 一
一 網路裝置驅動基礎 1.乙太網基礎理論 乙太網是區域網的一種,它使用載波監聽多路訪問及衝突檢測技術 csma cd 並以10m s的速率執行在多種型別的電纜上,常用的網絡卡晶元有dm9000 dm9161 cs8900晶元。乙太網的拓撲結構有匯流排型和星型,乙太網的工作模式有半雙工和全雙工。目前雙...