Linux網絡設備驅動程序培訓教材_第1頁
Linux網絡設備驅動程序培訓教材_第2頁
Linux網絡設備驅動程序培訓教材_第3頁
Linux網絡設備驅動程序培訓教材_第4頁
Linux網絡設備驅動程序培訓教材_第5頁
已閱讀5頁,還剩24頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、 Linux網絡設備驅動程序網絡設備驅動程序 第9章本章目標本章目標 了解Linux網絡驅動程序的數(shù)據交換過程 掌握移植和編寫具體網卡驅動程序的方法 本章結構本章結構Linux網絡設備驅動程序網絡設備驅動程序Linux網絡設備驅動的結構網絡設備驅動的結構 網絡設備的注冊、注銷和初始化網絡設備的注冊、注銷和初始化 網絡設備的打開和釋放網絡設備的打開和釋放 數(shù)據包發(fā)送數(shù)據包發(fā)送 數(shù)據包接收數(shù)據包接收 網絡連接狀態(tài)網絡連接狀態(tài) 參數(shù)設置和統(tǒng)計數(shù)據參數(shù)設置和統(tǒng)計數(shù)據 Linux網絡設備簡介網絡設備簡介 網絡設備,又叫網絡接口是Linux第三類標準設備 網絡設備和塊設備類似,在內核的特定數(shù)據結構中注冊自

2、己 當發(fā)生網絡數(shù)據交換時,網絡設備驅動程序注冊的方法將被內核調用 網絡設備不會在/dev下存在一個設備入口,它使用保留的內部設備名網絡設備的特點網絡設備的特點 網絡設備異步的接收外來的數(shù)據包,有別于其他設備 網絡設備主動的“請求”將硬件獲得的數(shù)據包壓入內核,而其他設備例如塊設備被“請求”向內核發(fā)送緩沖區(qū) 網絡設備同時要執(zhí)行大量的管理任務 設置地址 修改傳輸參數(shù) 維護流量和流量控制 錯誤統(tǒng)計和報告網絡設備的特點網絡設備的特點 網絡子系統(tǒng)是完全與協(xié)議無關的, 網絡驅動程序與內核其余部分之間的每次交互處理的都是一個網絡數(shù)據包9.1 Linux網絡設備驅動的結構網絡設備驅動的結構9.1.1 網絡協(xié)議接

3、口層網絡協(xié)議接口層 最主要的功能是給上層協(xié)議提供了透明的數(shù)據包發(fā)送最主要的功能是給上層協(xié)議提供了透明的數(shù)據包發(fā)送和接收接口。和接收接口。 上層上層ARP或或IP協(xié)議需要發(fā)送數(shù)據包時,調用網絡協(xié)議協(xié)議需要發(fā)送數(shù)據包時,調用網絡協(xié)議接口層的接口層的dev_queue_xmit()函數(shù)函數(shù) 上層對數(shù)據包的接收也通過向上層對數(shù)據包的接收也通過向netif_rx()函數(shù)函數(shù):8dev_queue_xmit(struct sk_buff *skb); int netif_rx(struct sk_buff *skb);89.1.1 網絡協(xié)議接口層網絡協(xié)議接口層套接字緩沖區(qū)套接字緩沖區(qū)(sk_buff)結結

4、構構套接字緩沖區(qū)(sk_buff)結構是Linux內核網絡子系統(tǒng)的核心內容,在中被定義sk_buff結構中的重要字段:struct net_device *rx_dev; struct net_device *dev;union /* . */ h;union /* . . . */ nh;union /*. */ mac;unsigned char *head;unsigned char *data;unsigned char *tail;unsigned char *end;unsigned long len;unsigned char ip_summed;unsigned char pk

5、t_type分別為接收和發(fā)送緩沖區(qū)的設備分別為接收和發(fā)送緩沖區(qū)的設備指向數(shù)據包中各個層的數(shù)據包頭。指向數(shù)據包中各個層的數(shù)據包頭。h指向傳指向傳輸層包頭,輸層包頭,nh指向網絡層包頭,指向網絡層包頭,mac指向指向鏈路層包頭鏈路層包頭用來尋址數(shù)據包中的數(shù)據指針。用來尋址數(shù)據包中的數(shù)據指針。head指向指向已分配空間開頭,已分配空間開頭,data指向有效的指向有效的octet開開頭,頭,tail指向有效的指向有效的octet結尾,而結尾,而end指向指向tail可以到達的最大地址可以到達的最大地址P A C K E T _ H O S T PACKET_BROADCAST PACKET_MULTI

6、CASTPACKET_OTHERHOST9.1.1 網絡協(xié)議接口層網絡協(xié)議接口層struct sk_buff *alloc_skb(unsigned int len, int priority);struct sk_buff *dev_alloc_skb(unsigned int len);void kfree_skb(struct sk_buff *skb);void dev_kfree_skb(struct sk_buff *skb);unsigned char *skb_put(struct sk_buff *skb, int len);unsigned char *_ _skb_put

7、(struct sk_buff *skb, int len);在緩沖區(qū)末尾添加數(shù)據,前在緩沖區(qū)末尾添加數(shù)據,前一個函數(shù)會進行檢查一個函數(shù)會進行檢查釋放套接字緩沖區(qū)釋放套接字緩沖區(qū)分配套接字緩沖區(qū)分配套接字緩沖區(qū)109.1.1 網絡協(xié)議接口層網絡協(xié)議接口層unsigned char *skb_push(struct sk_buff *skb, int len);unsigned char *_ _skb_push(struct sk_buff *skb, int len);緩沖區(qū)頭部添加數(shù)據緩沖區(qū)頭部添加數(shù)據int skb_tailroom(struct sk_buff *skb);void s

8、kb_reserve(struct sk_buff *skb, int len);unsigned char *skb_pull(struct sk_buff *skb, int len);int skb_headroom(struct sk_buff *skb);返回緩沖區(qū)后部可用空間總量返回緩沖區(qū)后部可用空間總量返回緩沖區(qū)前面部分可用空間總量返回緩沖區(qū)前面部分可用空間總量在可填充緩沖區(qū)之前保留包頭空間在可填充緩沖區(qū)之前保留包頭空間從數(shù)據包頭拿出數(shù)據,通常用來剝離數(shù)據包頭從數(shù)據包頭拿出數(shù)據,通常用來剝離數(shù)據包頭119.1.2 網絡設備接口層網絡設備接口層 net_device 結構結構該結構

9、是網絡設備驅動的核心,它包含了許多成員??梢詤⒖嘉募喿x它的完整定義。net_device結構可分為 全局成員 硬件相關成員 接口相關成員 設備方法成員 公用成員129.1.2 網絡設備接口層網絡設備接口層net_device 結構的主要成員結構的主要成員全局信息全局信息 char nameIFNAMESIZ int (*init)(struct net_device *dev)硬件信息硬件信息 unsigned long rmem_end; unsigned long rmem_start; unsigned long mem_end; unsigned long mem_start; u

10、nsigned long base_addr; unsigned char irq; unsigned char if_port; unsigned char dma;如果被設置了,在如果被設置了,在register_netdev獎獎調用他初始化調用他初始化net_device結構,現(xiàn)代結構,現(xiàn)代驅動一般在注冊接口中完成初始化。驅動一般在注冊接口中完成初始化。這些字段描述了設備共享內存的這些字段描述了設備共享內存的起止地址起止地址描述設備的描述設備的I/O基地址基地址描述設備中斷號描述設備中斷號描述多端口設備的活動端口描述多端口設備的活動端口描述設備的描述設備的DMA通道通道9.1.2 網絡設

11、備接口層網絡設備接口層 接口信息int (*open)(struct net_device *dev);int (*stop)(struct net_device *dev);int (*hard_start_xmit) (struct sk_buff *skb, struct net_device *dev);int (*hard_header) (struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len);打開接口。當打開接口。當ifcon

12、fig激活網絡設備時,激活網絡設備時,接口被打開。通常我們在接口被打開。通常我們在open方法里方法里面完成資源的分配,包括面完成資源的分配,包括I/O映射、中映射、中斷注冊、斷注冊、DMA注冊等。同時激活硬件,注冊等。同時激活硬件,并增加使用計數(shù)并增加使用計數(shù)停止接口。在這個方法里面,我們完停止接口。在這個方法里面,我們完成與成與open方法相反的,注銷操作方法相反的,注銷操作該方法初始化數(shù)據包的傳輸。是網絡設備驅動中非常重要的一個方法。我們將該方法初始化數(shù)據包的傳輸。是網絡設備驅動中非常重要的一個方法。我們將完整的數(shù)據包放入一個套接字緩沖區(qū)完整的數(shù)據包放入一個套接字緩沖區(qū)sk_buff結構

13、里結構里根據先前檢索到的源和目的硬件地址建立硬件頭根據先前檢索到的源和目的硬件地址建立硬件頭9.1.2 網絡設備接口層網絡設備接口層int (*rebuild_header)(struct sk_buff *skb);void (*tx_timeout)(struct net_device *dev);struct net_device_stats *(*get_stats)(struct net_device *dev);int (*set_config)(struct net_device *dev, struct ifmap *map);int (*do_ioctl)(struct ne

14、t_device *dev, struct ifreq *ifr, int cmd);void (*set_multicast_list)(struct net_device *dev);用來在傳輸數(shù)據包之前重建硬件頭用來在傳輸數(shù)據包之前重建硬件頭數(shù)據包發(fā)送在超時時間內失敗,這時數(shù)據包發(fā)送在超時時間內失敗,這時該方法被調用。這個方法應該解決失該方法被調用。這個方法應該解決失敗的問題并重新開始發(fā)送數(shù)據包敗的問題并重新開始發(fā)送數(shù)據包當應用程序需要獲得接口的統(tǒng)計信息時,這個方法被調用當應用程序需要獲得接口的統(tǒng)計信息時,這個方法被調用改變接口的配置。比如改變改變接口的配置。比如改變I/O端口和中斷號端

15、口和中斷號等,現(xiàn)在的驅動程序通常無需該方法等,現(xiàn)在的驅動程序通常無需該方法實現(xiàn)設備自定義的實現(xiàn)設備自定義的ioctl命令命令當設備的組播列表改變或設備當設備的組播列表改變或設備標志改變時,該方法被調用標志改變時,該方法被調用9.1.2 網絡設備接口層網絡設備接口層int (*set_mac_address)(struct net_device *dev, void *addr);int (*change_mtu)(struct net_device *dev, int new_mtu);int (*header_cache) (struct neighbour *neigh, struct h

16、h_cache *hh);int (*hard_header_parse) (struct sk_buff *skb, unsigned char *haddr);int (*header_cache_update) (struct hh_cache *hh, struct net_device *dev, unsigned char *haddr);如果接口支持如果接口支持MAC地址改地址改變,則可以實現(xiàn)該函數(shù)變,則可以實現(xiàn)該函數(shù)當接口的當接口的MTU改變時,改變時,該方法將被調用,負責該方法將被調用,負責做出相應的特定處理做出相應的特定處理根據根據ARP查詢的結果填充查詢的結果填充hh_c

17、ache結構結構在發(fā)生變化時,該方法更新在發(fā)生變化時,該方法更新hh_cache結構中的目的地址結構中的目的地址從從skb中包含的數(shù)據包中獲得源地址,并中包含的數(shù)據包中獲得源地址,并將其復制到位于將其復制到位于haddr的緩沖區(qū)中的緩沖區(qū)中9.2.1 網絡設備的注冊、注銷網絡設備的注冊、注銷注注冊與注銷函冊與注銷函數(shù)數(shù)創(chuàng)創(chuàng)建建net_device 釋釋放放net_device int register_netdev(struct net_device *dev);void unregister_netdev(struct net_device *dev);struct net_device *

18、alloc_netdev(int sizeof_priv, const char *name, void (*setup)(struct net_device*); struct net_device *alloc_etherdev(int sizeof_priv); void free_netdev(struct net_device *dev);9.2.1 網絡設備的注冊、注銷網絡設備的注冊、注銷1 int xxx_init_module(void)2 3 4 /*分配net_device結構體并對其成員賦值*/5 xxx_dev = alloc_netdev(sizeof(struct

19、xxx_priv),“sn%d”, xxx_init);6if(xxx_dev = NULL)7/*分配net_device失敗*/89/*注冊net_device結構體*/10if(result = register_netdev(xxx_dev)1112 1314 void xxx_cleanup(void)15 1617/*注銷net_device結構體*/18 unregister_netdev(xxx_dev);19 /*釋放net_device結構體*/20 free_netdev(xxx_dev);21 189.3 網絡設備的打開和釋放網絡設備的打開和釋放 網絡設備的打開函數(shù)完成

20、如下工作:網絡設備的打開函數(shù)完成如下工作:使能設備使用的硬件資源,申請I/O區(qū)域、中斷和DMA通道等。調用Linux內核提供的netif_start_queue()函數(shù),激活設備發(fā)送隊列。 網絡設備的關閉函數(shù)需要完成如下工作:網絡設備的關閉函數(shù)需要完成如下工作:調用Linux內核提供的netif_stop_queue()函數(shù),停止設備傳輸包。釋放設備所使用的I/O區(qū)域、中斷和DMA資源。 netif_start_queue()和和netif_stop_queue()兩個函數(shù)的原型兩個函數(shù)的原型void netif_start_queue(struct net_device *dev);void

21、 netif_stop_queue(struct net_device *dev);199.3 網絡設備的打開和釋放網絡設備的打開和釋放int xxx_open(struct net_device *dev) /*申請端口、IRQ等,類似于fops-open */ ret = request_irq(dev-irq, &xxx_interrupt, 0, dev-name, dev); netif_start_queue(dev); int xxx_release(struct net_device *dev) /*釋放端口、IRQ等,類似于fops-close*/ free_irq(

22、dev-irq, dev); netif_stop_queue(dev); /*cant transmit any more*/ 9.4 數(shù)據包發(fā)送數(shù)據包發(fā)送 網絡設備驅動完成數(shù)據包發(fā)送的流程如下:網絡設備驅動完成數(shù)據包發(fā)送的流程如下:網絡設備驅動程序從上層協(xié)議傳遞過來的sk_buff參數(shù)獲得數(shù)據包的有效數(shù)據和長度,將有效數(shù)據放入臨時緩沖區(qū)。對于以太網,如果有效數(shù)據的長度小于以太網沖突檢測所要求數(shù)據幀的最小長度ETH_ZLEN,則給臨時緩沖區(qū)的末尾填充0。設置硬件的寄存器,驅使網絡設備進行數(shù)據發(fā)送操作。219.4 數(shù)據包發(fā)數(shù)據包發(fā)送送1 int xxx_tx(struct sk_buff *s

23、kb, struct net_device *dev)2 3 int len;4 char *data, shortktETH_ZLEN;5 /*獲得有效數(shù)據指針和長度*/6 data = skb-data;7 len = skb-len;8 if(len data, skb-len);13 len = ETH_ZLEN;14data = shortpkt;15 17dev-trans_start = jiffies; /*記錄發(fā)送時間戳*/ 19 /*設置硬件寄存器讓硬件把數(shù)據包發(fā)送出去*20 xxx_hw_tx(data, len, dev);21 22 9.4 數(shù)據包發(fā)送數(shù)據包發(fā)送 傳輸

24、超時處理傳輸超時處理當數(shù)據傳輸超時時,意味著當前的發(fā)送操作失敗,此時,數(shù)據包發(fā)送超時處理函數(shù)xxx_tx_timeout將被調用。這個函數(shù)需要調用Linux內核提供的netif_wake_queue()函數(shù)重新啟動設備發(fā)送隊列。如下所示:231void xxx_tx_timeout(struct net_device *dev)234netif_ wake_queue(dev);/*重新啟動設備發(fā)送隊列重新啟動設備發(fā)送隊列*/5239.5 數(shù)據包接數(shù)據包接收收網絡設備接收數(shù)據的主要方法是由中斷引發(fā)設備的中斷處理函數(shù),中斷處理函數(shù)判斷中斷類型,如果為接收中斷,則讀取接收到的數(shù)據,分配sk_buf

25、fer數(shù)據結構和數(shù)據緩沖區(qū)將接收到的數(shù)據復制到數(shù)據緩沖區(qū),并調用netif_rx()函數(shù)將sk_buffer傳遞給上層協(xié)議。 9.5 數(shù)據包接數(shù)據包接收收static void xxx_interrupt(int irq, void *dev_id, struct pt_regs *regs) switch(status & ISQ_EVENT_MASK) case ISQ_RECEIVER_EVENT:/*獲取數(shù)據包*/xxx_rx(dev);break;/*其他類型的中斷*/ static void xxx_rx(struct xxx_device *dev)length = ge

26、t_rev_len();/*分配新的套接字緩沖區(qū)分配新的套接字緩沖區(qū)*/skb = dev_alloc_skb(length + 2);skb = reserve(skb, 2); /*對齊對齊*/skb-dev = dev;/*讀取硬件上接收到的數(shù)據讀取硬件上接收到的數(shù)據*/insw(ioaddr + RX_FRAME_PORT, skb_put(skb, length), length 1);if(length & l) skb-datalength 1 = inw(ioaddr + RX_FRAME_PORT); /*獲取上層協(xié)議類型獲取上層協(xié)議類型*/skb-protocol = eth_type_trans(skb, dev);netif_rx(skb) ; /*把數(shù)據包交給上層把數(shù)據包交給上層*/dev-last_rx = jiffies ; /*記錄接收時間戳記錄接收時間戳*/.259.6 網絡連接狀態(tài)網絡連接狀態(tài) 網絡適配器硬件電路可以檢測出鏈路上是否有載波,網絡適配器硬件電路可以檢測出鏈路上是否有載波,載波反映了網絡的連接是否正常。載波反映了網絡的連接是否正常。 網絡設備驅動可以通過如下函數(shù)通知網絡的連接狀態(tài):網絡設備驅動可以通過如下函數(shù)通知網絡的連接狀態(tài): 網絡設備驅動程序中往往設置一個定時器來對鏈路狀網絡設備驅動程序中往往

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論