娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2025年07月07日(星期一)

2020年07月07日 | S3C2440 網(wǎng)卡驅(qū)動介紹以及制作虛擬網(wǎng)卡驅(qū)動(二十五)

發(fā)布者:溫柔的愛情 來源: eefocus關(guān)鍵字:S3C2440  網(wǎng)卡驅(qū)動  虛擬網(wǎng)卡驅(qū)動 手機(jī)看文章 掃描二維碼
隨時隨地手機(jī)看文章

1、描述


網(wǎng)卡的驅(qū)動其實很簡單,它還是與硬件相關(guān),主要是負(fù)責(zé)收發(fā)網(wǎng)絡(luò)的數(shù)據(jù)包,它將上層協(xié)議傳遞下來的數(shù)據(jù)包以特定的媒介訪問控制方式進(jìn)行發(fā)送,并將接受到的數(shù)據(jù)包傳遞給上層協(xié)議。


網(wǎng)卡設(shè)備與字符設(shè)備和塊設(shè)備不同,網(wǎng)絡(luò)設(shè)備并不對應(yīng)于/dev/目錄下的文件,不過會存放在/sys/class/net目錄下

2、Linux系統(tǒng)對網(wǎng)絡(luò)設(shè)備驅(qū)動定義了4個層次,這4個層次有到下分為:


1)網(wǎng)絡(luò)協(xié)議接口層:


實現(xiàn)統(tǒng)一的數(shù)據(jù)包收發(fā)的協(xié)議,該層主要負(fù)責(zé)調(diào)用dev_queue_xmit()函數(shù)發(fā)送數(shù)據(jù),netif_rx()函數(shù)接收數(shù)據(jù)


2)網(wǎng)絡(luò)設(shè)備接口層:


通過net_device結(jié)構(gòu)體來描述一個具體的網(wǎng)絡(luò)設(shè)備的信息,實現(xiàn)不同的硬件的統(tǒng)一


3)設(shè)備驅(qū)動功能層:


用來負(fù)責(zé)驅(qū)動網(wǎng)路設(shè)備硬件來完成各個功能,它通過hard_start_xmit()函數(shù)啟動發(fā)送操作,并通過網(wǎng)絡(luò)設(shè)備上的中斷觸發(fā)接收操作


4)網(wǎng)絡(luò)設(shè)備與媒體層:


用來負(fù)責(zé)完成數(shù)據(jù)包發(fā)送和接受的物理實體,設(shè)備驅(qū)動功能層的函數(shù)都在這物理上驅(qū)動的


層次結(jié)構(gòu)如下圖所示:


3、網(wǎng)卡驅(qū)動初始化


而我們的網(wǎng)卡驅(qū)動程序,只需要編寫網(wǎng)絡(luò)設(shè)備接口層,填充net_device數(shù)據(jù)結(jié)構(gòu)的內(nèi)容并將net_device注冊入內(nèi)核,設(shè)置硬件相關(guān)操作,使能中斷處理等。


3.1 其中net_device結(jié)構(gòu)體的重要成員,整理后如下所示:


struct net_device

{

       char               name[IFNAMSIZ];              //網(wǎng)卡設(shè)備名稱

       unsigned long              mem_end;             //該設(shè)備的內(nèi)存結(jié)束地址

       unsigned long              mem_start;            //該設(shè)備的內(nèi)存起始地址

       unsigned long              base_addr;            //該設(shè)備的內(nèi)存I/O基地址

       unsigned int          irq;                       //該設(shè)備的中斷號

 

       unsigned char        if_port;                  //多端口設(shè)備使用的端口類型

    unsigned char        dma;                     //該設(shè)備的DMA通道

 

       unsigned long              state;                    //網(wǎng)絡(luò)設(shè)備和網(wǎng)絡(luò)適配器的狀態(tài)信息


      struct net_device_stats* (*get_stats)(struct net_device *dev); //獲取流量的統(tǒng)計信息

                        //運(yùn)行ifconfig便會調(diào)用該成員函數(shù),并返回一個net_device_stats結(jié)構(gòu)體獲取信息

 

      struct net_device_stats  stats;      //用來保存統(tǒng)計信息的net_device_stats結(jié)構(gòu)體

 

 

       unsigned long              features;        //接口特征,     

       unsigned int          flags; //flags指網(wǎng)絡(luò)接口標(biāo)志,以IFF_(Interface Flags)開頭

//當(dāng)flags =IFF_UP( 當(dāng)設(shè)備被激活并可以開始發(fā)送數(shù)據(jù)包時, 內(nèi)核設(shè)置該標(biāo)志)、 IFF_AUTOMEDIA(設(shè)置設(shè)備可在多種媒介間切換)、

IFF_BROADCAST( 允許廣播)、IFF_DEBUG( 調(diào)試模式, 可用于控制printk調(diào)用的詳細(xì)程度) 、 IFF_LOOPBACK( 回環(huán))、

IFF_MULTICAST( 允許組播) 、 IFF_NOARP( 接口不能執(zhí)行ARP,點對點接口就不需要運(yùn)行 ARP) 和IFF_POINTOPOINT( 接口連接到點到點鏈路) 等。

 

 

       unsigned        mtu;        //最大傳輸單元,也叫最大數(shù)據(jù)

 

       unsigned short  type;     //接口的硬件類型

 

       unsigned short   hard_header_len;     //硬件幀頭長度,一般被賦為ETH_HLEN,即14

 

 

    unsigned char   dev_addr[MAX_ADDR_LEN];      //存放設(shè)備的MAC地址

 

       unsigned long              last_rx;    //接收數(shù)據(jù)包的時間戳,調(diào)用netif_rx()后賦上jiffies即可

 

       unsigned long              trans_start;     //發(fā)送數(shù)據(jù)包的時間戳,當(dāng)要發(fā)送的時候賦上jiffies即可

 

       unsigned char        dev_addr[MAX_ADDR_LEN];                //MAC地址

 

 

       int                 (*hard_start_xmit) (struct sk_buff *skb, struct net_device *dev);

                                   //數(shù)據(jù)包發(fā)送函數(shù), sk_buff就是用來收發(fā)數(shù)據(jù)包的結(jié)構(gòu)體

 

 

    void  (*tx_timeout) (struct net_device *dev); //發(fā)包超時處理函數(shù)

    ... ...

}

上面提到的統(tǒng)計信息net_device_stats結(jié)構(gòu)體,其中重要成員如下所示:


struct net_device_stats

{

       unsigned long       rx_packets;            /*收到的數(shù)據(jù)包數(shù)*/

       unsigned long       tx_packets;            /*發(fā)送的數(shù)據(jù)包數(shù)    */

       unsigned long       rx_bytes;               /*收到的字節(jié)數(shù),可以通過sk_buff結(jié)構(gòu)體的成員len來獲取*/

       unsigned long       tx_bytes;               /*發(fā)送的字節(jié)數(shù),可以通過sk_buff結(jié)構(gòu)體的成員len來獲取*/

       unsigned long       rx_errors;              /*收到的錯誤數(shù)據(jù)包數(shù)*/

       unsigned long       tx_errors;              /*發(fā)送的錯誤數(shù)據(jù)包數(shù)*/

       ... ...

}

3.2 所以init()函數(shù),初始化網(wǎng)卡步驟如下所示:

1) 使用alloc_netdev()來分配一個net_device結(jié)構(gòu)體


2) 設(shè)置網(wǎng)卡硬件相關(guān)的寄存器


3) 設(shè)置net_device結(jié)構(gòu)體的成員


4) 使用register_netdev()來注冊net_device結(jié)構(gòu)體


4、網(wǎng)卡驅(qū)動發(fā)包過程


在內(nèi)核中,當(dāng)上層要發(fā)送一個數(shù)據(jù)包時,就會調(diào)用網(wǎng)絡(luò)設(shè)備層里net_device數(shù)據(jù)結(jié)構(gòu)的成員hard_start_xmit()將數(shù)據(jù)包發(fā)送出去。


hard_start_xmit()發(fā)包函數(shù)需要我們自己構(gòu)建,該函數(shù)原型如下所示:


int    (*hard_start_xmit) (struct sk_buff *skb, struct net_device *dev);

在這個函數(shù)中,需要涉及到sk_buff結(jié)構(gòu)體,含義為(socket buffer)套接字緩沖區(qū),用來網(wǎng)絡(luò)各個層次之間傳遞數(shù)據(jù)。


4.1 sk_buff結(jié)構(gòu)體是一個雙向鏈表,其中重要成員如下所示:


struct sk_buff {

       /* These two members must be first. */

       struct sk_buff        *next;      //指向下一個sk_buff結(jié)構(gòu)體

       struct sk_buff        *prev;     //指向前一個sk_buff結(jié)構(gòu)體

    ... ...

       unsigned int          len,         //數(shù)據(jù)包的總長度,包括線性數(shù)據(jù)和非線性數(shù)據(jù)

                            data_len,        //非線性的數(shù)據(jù)長度

                            mac_len;         //mac包頭長度

 

    __u32          priority;          //該sk_buff結(jié)構(gòu)體的優(yōu)先級   

 

    __be16        protocol;           //存放上層的協(xié)議類型,可以通過eth_type_trans()來獲取

       ... ...

 

      sk_buff_data_t              transport_header;    //傳輸層頭部的偏移值

      sk_buff_data_t              network_header;     //網(wǎng)絡(luò)層頭部的偏移值

      sk_buff_data_t              mac_header;          //MAC數(shù)據(jù)鏈路層頭部的偏移值

 

    sk_buff_data_t              tail;                    //指向緩沖區(qū)的數(shù)據(jù)包末尾

      sk_buff_data_t              end;                     //指向緩沖區(qū)的末尾

      unsigned char            *head,                   //指向緩沖區(qū)的協(xié)議頭開始位置

                                  *data;                   //指向緩沖區(qū)的數(shù)據(jù)包開始位置

       ... ...

}

其中sk_buff結(jié)構(gòu)體的空間,如下圖所示:



其中sk_buff->data數(shù)據(jù)包格式如下圖所示:



4.2 所以,hard_start_xmit()發(fā)包函數(shù)處理步驟如下所示:


1)數(shù)據(jù)包發(fā)送出去之前,需要使用netif_stop_queue()來停止上層傳下來的數(shù)據(jù)包


2)設(shè)置寄存器,通過網(wǎng)絡(luò)設(shè)備硬件,來發(fā)送數(shù)據(jù)


3)當(dāng)數(shù)據(jù)包發(fā)出去后,再調(diào)用dev_free_skb()函數(shù)來釋放sk_buff,該函數(shù)原型如下:


void dev_kfree_skb(struct sk_buff *skb);   

4)當(dāng)數(shù)據(jù)包發(fā)出成功,就會進(jìn)入TX中斷函數(shù),然后更新統(tǒng)計信息,調(diào)用netif_wake_queue來喚醒,啟動上層繼續(xù)發(fā)數(shù)據(jù)包下來


5)若數(shù)據(jù)包發(fā)出去超時,一直進(jìn)不到TX中斷函數(shù),就會調(diào)用net_device結(jié)構(gòu)體的(*tx_timeout)超時成員函數(shù),在該函數(shù)中更新


統(tǒng)計信息,調(diào)用netif_wake_queue()來喚醒


其中netif_wake_queue()和netif_stop_queue()函數(shù)原型如下所示:


void netif_wake_queue(struct net_device *dev);  //喚醒被阻塞的上層,啟動繼續(xù)向網(wǎng)絡(luò)設(shè)備驅(qū)動層發(fā)送數(shù)據(jù)包

 

void netif_stop_queue(struct net_device *dev); //阻止上層向網(wǎng)絡(luò)設(shè)備驅(qū)動層發(fā)送數(shù)據(jù)包

 

5、網(wǎng)卡驅(qū)動收包過程


而接收數(shù)據(jù)包主要是通過中斷函數(shù)處理,來判斷中斷類型,如果等于ISQ_RECEIVER_EVENT,表示為接受中斷,然后進(jìn)入接收數(shù)據(jù)函數(shù),通過netif_rx()將數(shù)據(jù)上交給上層


例如下圖所示,參考的內(nèi)核中自帶的網(wǎng)卡驅(qū)動:drivers/net/cs89x0.c


如上圖所示,通過獲取的status標(biāo)志來判斷是什么中斷,如果是接受中斷,就進(jìn)入net_rx()


5.1 其中net_rx()收包函數(shù)處理步驟如下所示:


1)使用dev_alloc_skb()來構(gòu)造一個新的sk_buff


2)使用skb_reserve(rx_skb,2);將sk_buff緩沖區(qū)里的數(shù)據(jù)包先后位移2字節(jié),來騰出sk_buff緩沖區(qū)里的頭部空間


3)讀取網(wǎng)絡(luò)設(shè)備硬件上接收到的數(shù)據(jù)


4)使用memcpy()將數(shù)據(jù)復(fù)制到新的sk_buff里的data成員指向的地址處,可以使用skb_put()來動態(tài)擴(kuò)大sk_buff結(jié)構(gòu)體里中的數(shù)據(jù)區(qū)


5)使用eth_type_trans()來獲取上層協(xié)議,將返回值賦給sk_buff的protocol成員里


6)然后更新統(tǒng)計信息,最后使用netif_rx()來將sk_buffer傳遞給上層協(xié)議中


其中skb_put()函數(shù)原型如下所示:


static inline unsigned char *skb_put(struct sk_buff *skb, unsigned int len);

//len:將數(shù)據(jù)區(qū)向下擴(kuò)大len字節(jié)

使用skb_put()函數(shù)后,其中sk_buff緩沖區(qū)變化如下圖:


6、寫虛擬網(wǎng)卡驅(qū)動


本屆便開始來寫一個簡單的虛擬網(wǎng)卡驅(qū)動,也就是說不需要硬件相關(guān)操作,所以就沒有中斷函數(shù),我們通過linux的ping命令來實現(xiàn)發(fā)包,然后在發(fā)包函數(shù)中,偽造一個收的ping包函數(shù),實現(xiàn)ping通任何ip地址

在init初始函數(shù)中:


1)使用alloc_netdev()來分配一個net_device結(jié)構(gòu)體


2)設(shè)置net_device結(jié)構(gòu)體的成員


3)使用register_netdev()來注冊net_device結(jié)構(gòu)體


在發(fā)包函數(shù)中:


1)使用netif_stop_queue()來阻止上層向網(wǎng)絡(luò)設(shè)備驅(qū)動層發(fā)送數(shù)據(jù)包


2)調(diào)用收包函數(shù),并代入發(fā)送的sk_buff緩沖區(qū),里面來偽造一個收的ping包函數(shù)


3)使用dev_kfree_skb()函數(shù)來釋放發(fā)送的sk_buff緩存區(qū)


4)更新發(fā)送的統(tǒng)計信息


5)使用netif_wake_queue()來喚醒被阻塞的上層


在收包函數(shù)中:


首先修改發(fā)送的sk_buff里數(shù)據(jù)包的數(shù)據(jù),使它變?yōu)橐粋€接受的sk_buff,其中數(shù)據(jù)包結(jié)構(gòu)如下圖所示:




1)需要對調(diào)上的ethhdr結(jié)構(gòu)體“源/目的”MAC地址


2)需要對調(diào)上圖的iphdr結(jié)構(gòu)體"源/目的"IP地址


3)使用ip_fast_csum()來重新獲取iphdr結(jié)構(gòu)體的校驗碼


4)設(shè)置上圖數(shù)據(jù)包的數(shù)據(jù)類型,之前是發(fā)送ping包0x08,需要改為0x00,表示接受ping包


5)使用dev_alloc_skb()來構(gòu)造一個新的sk_buff


6)使用skb_reserve(rx_skb,2);將sk_buff緩沖區(qū)里的數(shù)據(jù)包先后位移2字節(jié),來騰出sk_buff緩沖區(qū)里的頭部空間


7)使用memcpy()將之前修改好的sk_buff->data復(fù)制到新的sk_buff里的data成員指向的地址處


memcpy(skb_put(rx_skb, skb->len), skb->data, skb->len);

// skb_put():來動態(tài)擴(kuò)大sk_buff結(jié)構(gòu)體里中的數(shù)據(jù)區(qū),避免溢出

8)設(shè)置新的sk_buff其它成員


9)使用eth_type_trans()來獲取上層協(xié)議,將返回值賦給sk_buff的protocol成員里


10)然后更新接收統(tǒng)計信息,最后使用netif_rx()來將sk_fuffer傳遞給上層協(xié)議中


 


7、驅(qū)動具體代碼如下:


 

/* 參考

 * driversnetcs89x0.c

 */

 

#include

#include

#include

#include

#include

#include

[1] [2]
關(guān)鍵字:S3C2440  網(wǎng)卡驅(qū)動  虛擬網(wǎng)卡驅(qū)動 引用地址:S3C2440 網(wǎng)卡驅(qū)動介紹以及制作虛擬網(wǎng)卡驅(qū)動(二十五)

上一篇:S3C2440 Nor Flash驅(qū)動(二十四)
下一篇:S3C2440 熱拔插驅(qū)動 修改mdev配置支持U盤自動掛載(三十三)

推薦閱讀

天貓精靈是阿里巴巴人工智能實驗室的AI智能產(chǎn)品品牌,旗下?lián)碛卸嗫钪悄芤粝洚a(chǎn)品,通過語音與用戶進(jìn)行交互,是目前智能音箱中用戶最多的之一。?據(jù)天貓精靈官方消息,天貓精靈今日獲得了7月份首次系統(tǒng)升級,優(yōu)化了一些功能,新增了組合口令。?組合口令就是能夠讓天貓精靈執(zhí)行多個指令,比如設(shè)置口令“我回來了”,天貓精靈就會打開燈+打開空調(diào)+打開電視...
富士康可以說是我國有頭有臉的工廠了,它以流水線的生產(chǎn)運(yùn)作方式而著名,在國內(nèi)的許多工廠里非常有名。富士康大多負(fù)責(zé)一些加工產(chǎn)品的業(yè)務(wù),在前些年與美國的蘋果手機(jī)平臺合作頻繁。隨著蘋果銷售量的部分增加,富士康的業(yè)務(wù)拓展也越來越大,兩者可以說是形成了互利共贏的局面。 雖然富士康與蘋果公司的合作很多,但是并沒有涉及到一些核心技術(shù)和高科技...
國內(nèi)引入自動駕駛的汽車廠商數(shù)量逐步普及,背后的技術(shù)也將得到更大的重視和市場。 完成 B1 融資,擴(kuò)大 L2+自動駕駛規(guī)模近日,知行科技宣布完成 B1 輪融資,此前知行科技曾先后獲得過 3 輪近億融資,本輪融資金額近億元,將主要用于 L2 級自動駕駛的量產(chǎn)規(guī)模擴(kuò)大及 L2+自動駕駛量產(chǎn)推進(jìn)。 本次 B1 輪融資,由建銀蘇州科創(chuàng)基金領(lǐng)投,禾裕壹號跟...
聞泰科技全資子公司安世半導(dǎo)體宣布已完成收購英國新港晶圓廠(Newport Wafer Fab)的交易協(xié)議簽署。在全球汽車產(chǎn)業(yè)面臨“芯片荒”的大背景下,此次收購可助力安世半導(dǎo)體實現(xiàn)增長目標(biāo)和投資,進(jìn)一步提高全球產(chǎn)能。為了化解汽車“芯”事,包括安世半導(dǎo)體在內(nèi)的IDM和晶圓廠都在積極提升產(chǎn)能,并尋求產(chǎn)業(yè)鏈上下游更加敏捷有效的協(xié)同互動。 擴(kuò)大車規(guī)級產(chǎn)品市...

史海拾趣

問答坊 | AI 解惑

Wi-Fi 聯(lián)盟在華新增認(rèn)證測試實驗室

Wi-Fi 聯(lián)盟 (Wi-Fi Alliance) 宣布,上海同耀通信技術(shù)有限公司最近成為該公司最新的授權(quán)測試實驗室 (ATL),在中國主要的經(jīng)濟(jì)中心之一上海為其全球會員公司提供獨立測試服務(wù)。該實驗室于上月底完成了對其首個 Wi-Fi CERTIFIED 產(chǎn)品的測試。   同 ...…

查看全部問答∨

用Virtex-6和Spartan-6 FPGA構(gòu)建功耗優(yōu)化的設(shè)計

  隨著元件選擇和功耗管理技術(shù)日益成為影響系統(tǒng)設(shè)計成功與否的重要考慮因素,工程師也越來越多地將其注意力集中到功耗上。 賽靈思采用了整體分析法來確保系統(tǒng)設(shè)計者能夠利用Virtex®-6和Spartan®-6 FPGA實現(xiàn)功耗優(yōu)化設(shè)計。     ...…

查看全部問答∨

視頻名詞解析(Video Demystified,950頁)

Video Demystified,主要與視頻處理的一些格式,例如HDMI,DVI,YPBPR,AV等等一些的解析,對于初級的知識普及比較適用。 [ 本帖最后由 xuezhilianz 于 2009-8-21 09:06 編輯 ]…

查看全部問答∨

lpc1343能否移植usosII

如題,想了解一下是否能跑系統(tǒng),除了ucosII,其他的系統(tǒng)也可以…

查看全部問答∨

eVC++ 編寫的客戶端程序!!!!

大家誰做過eVC++ 編寫的客戶端程序?? 可以向服務(wù)器端發(fā)送 信息和文件那種的。 急求!!!!!!…

查看全部問答∨

太陽能板充電

大家好。前些日子我買了一個5V170MA的太陽能板給我的電路充電,但是不知道能不能用。我的電路板主要是給電池充電,我的電池是2000MAH的容量,在太陽能板與點吃之間什么東西也沒加只是直接并在一起的。不知道能不能用?誰能告訴我一下呢?謝謝啦~~~…

查看全部問答∨

照明用LED封裝創(chuàng)新探討

一,常規(guī)現(xiàn)有的封裝方法及應(yīng)用領(lǐng)域     目前LED 的封裝方法有:支架排封裝,貼片封裝,模組封裝幾種,這些封裝方法都是我們常見和常用的。    支架排封裝是最早采用,用來生產(chǎn)單個LED器件,這就是我們常見的引線型發(fā) ...…

查看全部問答∨

MSP430中的Flash操作問題?

void FlashErase() { uchar *p0; FCTL2 = FWKEY + FSSEL_1 + FN3 + FN4;//選擇時鐘源,分頻 FCTL3 = FWKEY;//清除LOCK while(FCTL3 & BUSY);//如果出于忙,則等待 FCTL1 = FWKEY + ERASE;//使能段操作 p0 = (unsigned char *)0x1080;//數(shù)值 ...…

查看全部問答∨

電子產(chǎn)品開發(fā)中常遇電磁兼容EMC問題及解決辦法

一般電子產(chǎn)品都最容易出的問題有:RE--輻射,CE--傳導(dǎo),ESD--靜電。通訊類電子產(chǎn)品不光包括以上三項:RE,CE,ESD,還有Surge--浪涌(雷擊,打雷) 醫(yī)療器械最容易出現(xiàn)的問題是:ESD--靜電,EFT--瞬態(tài)脈沖抗干擾,CS--傳導(dǎo)抗干擾,RS--輻射抗干擾 ...…

查看全部問答∨
小廣播
設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號

 
EEWorld服務(wù)號

 
汽車開發(fā)圈

 
機(jī)器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號 京ICP備10001474號-1 電信業(yè)務(wù)審批[2006]字第258號函 京公網(wǎng)安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 海宁市| 孝义市| 永丰县| 根河市| 江川县| 屯留县| 尼勒克县| 吴江市| 翁源县| 宁化县| 徐闻县| 宝兴县| 花莲县| 许昌县| 灯塔市| 南城县| 十堰市| 岳池县| 江山市| 汕尾市| 临漳县| 南汇区| 青田县| 临沭县| 泰安市| 湘阴县| 汕头市| 纳雍县| 昭苏县| 虎林市| 雅安市| 揭阳市| 奉贤区| 肥乡县| 中江县| 宝清县| 积石山| 淄博市| 苍南县| 高雄县| 荣成市|