日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

网络设备驱动学习

發(fā)布時間:2024/3/13 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网络设备驱动学习 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

網(wǎng)絡(luò)設(shè)備驅(qū)動學(xué)習(xí)

概述:本周主要學(xué)習(xí)了網(wǎng)絡(luò)驅(qū)動層面的一些知識,最主要的學(xué)習(xí)目標(biāo)是基本弄清包的發(fā)送與接收的過程,這不僅涉及到了高層的協(xié)議與機制,底層的驅(qū)動與硬件,更要理解數(shù)據(jù)包的封裝與包格式。我們主要是圍繞著設(shè)備驅(qū)動開發(fā)的第十六章來學(xué)習(xí)這些內(nèi)容。

問題:對十六章進(jìn)行細(xì)化后發(fā)現(xiàn)主要可以歸結(jié)成對幾個問題的把握,包括數(shù)據(jù)包的承載問題,加包頭與去包頭的實現(xiàn),網(wǎng)絡(luò)的框架結(jié)構(gòu),網(wǎng)絡(luò)設(shè)備的注冊與注銷,數(shù)據(jù)的發(fā)送與接收流程。

正文:

一、數(shù)據(jù)包的承載問題

這個問題落到了結(jié)構(gòu)體sk_buff上,也就是套接字緩沖區(qū),根本上來講就是內(nèi)存中存放傳輸數(shù)據(jù)包的一塊內(nèi)存區(qū)域。此結(jié)構(gòu)體流動于各協(xié)議層之間,發(fā)送和接收時,用于添加協(xié)議頭與剝?nèi)f(xié)議頭,這兩個操作就是通過sk_buff里的四個指針域來實現(xiàn)的。下面來簡述這個關(guān)鍵結(jié)構(gòu)體的一些成員:

(1) .sk_buff中的各層協(xié)議頭:

采用了聯(lián)合體來描述各層的協(xié)議頭,分別描述了傳輸層h、網(wǎng)絡(luò)層nh和鏈路層mac中的各個協(xié)議頭,其中包括的成員主要就是各層的協(xié)議頭,還有指向所在層頭部的指針*raw

(2) .sk_buff4個數(shù)據(jù)指針:

head/end:套接字緩沖區(qū)的起始地址/終止地址

data/tail:協(xié)議數(shù)據(jù)區(qū)起始地址/終止地址

只要明白這四個指針是四個邊界就很好理解數(shù)據(jù)緩沖區(qū)的構(gòu)成了,尤其要知道data/tail之間存放的是有效數(shù)據(jù),這里可以理解成協(xié)議頭和用戶數(shù)據(jù)。

(3) .三個長度信息

len:協(xié)議數(shù)據(jù)包長度

data_len:記錄分片的數(shù)據(jù)長度

truesize:數(shù)據(jù)緩沖區(qū)的實際長度

由于數(shù)據(jù)鏈路層有最大傳輸單元MTU的限制,這就引入了分片的機制,這里主要是在網(wǎng)絡(luò)層由IP協(xié)議來實現(xiàn),其中有一個字段就是片偏移指針。相應(yīng)的在套接字緩沖區(qū)末尾有一個skb_shared_info結(jié)構(gòu)體,用于記錄分片的一些信息,frags即為分片數(shù)組,每一個分片長度的上限是一頁,即4KB大小,再配合長度信息data_len,這樣對于分片機制就比較理解了。

二、加包頭與去包頭

這個問題主要就是通過移動sk_buff里的四個指針域來實現(xiàn)的,這里不得不提的就是套接字緩沖區(qū)提供的四個指針移動函數(shù)。

這四個函數(shù)分別是put(放置)push()pull()reserve(保留) put函數(shù)用于將tail指針向后移動,主要是完成存放數(shù)據(jù)包的操作,push函數(shù)用于將data指針向前移動,主要是完成加協(xié)議頭的操作,

pull函數(shù)用于將data指針向后移動,主要是完成去協(xié)議頭的操作,

reserve函數(shù)用于將datatail指針同時后移,主要用于在存儲空間的頭部預(yù)留一部分空間,用時是用于協(xié)議頭對齊。

?????? 下面主要簡述一下接收包的過程:

?????? (1)、網(wǎng)卡收到一個數(shù)據(jù)包后,驅(qū)動程序創(chuàng)建一個sk_buff結(jié)構(gòu)體,在緩沖區(qū)頭部預(yù)留2個字節(jié)的空間用于協(xié)議頭的對齊,接著將收到的數(shù)據(jù)全部復(fù)制到data指向的空間,并將skb->mac.raw指向data

(2)、數(shù)據(jù)鏈路層調(diào)用skb_pull()函數(shù)剝掉以頭網(wǎng)協(xié)議頭(data指針下移一個以太網(wǎng)頭部的長度sizeof(ethhdr)len減去一個以太網(wǎng)頭部的長度,skb->nh.raw指向data位置),向網(wǎng)絡(luò)層傳遞數(shù)據(jù)包。

(3)、網(wǎng)絡(luò)層通過skb_pull()函數(shù)剝掉IP頭,向傳輸層傳遞數(shù)據(jù)包。去包頭過程于(2)類似,主要還是data指針和傳輸層包頭指針的下移。

(4)、應(yīng)用程序調(diào)用接收套接字接收數(shù)據(jù),并將數(shù)據(jù)復(fù)制到應(yīng)用層緩沖區(qū),接收的數(shù)據(jù)包括傳輸層包頭和負(fù)載,由此可見傳輸層包頭并不會被剝離。

三、體系架構(gòu)的理解

?? 在架構(gòu)的上面是四層網(wǎng)絡(luò)協(xié)議,下面是四個底層,包括網(wǎng)絡(luò)協(xié)議接口層、網(wǎng)絡(luò)設(shè)備接口層、設(shè)備驅(qū)動功能層、網(wǎng)絡(luò)設(shè)備與媒介層。sk_buff流動于四個協(xié)議層,用于數(shù)據(jù)包的承載。在網(wǎng)絡(luò)協(xié)議接口層有兩個函數(shù),分別用于數(shù)據(jù)包的發(fā)送dev_queue_xmit()函數(shù),數(shù)據(jù)包的接收netif_rx()函數(shù)。在網(wǎng)絡(luò)設(shè)備接口層有一個底層最關(guān)鍵的數(shù)據(jù)結(jié)構(gòu)net_device,這是個用于描述網(wǎng)絡(luò)設(shè)備屬性和操作接口的數(shù)據(jù)結(jié)構(gòu)。設(shè)備驅(qū)動功能層則提供了一些底層的操作,包括數(shù)據(jù)包發(fā)送hard_start_xmit(),中斷處理(數(shù)據(jù)包接收)等等,這些操作提供的接口都在net_device中存放著。網(wǎng)絡(luò)設(shè)備與媒介層則提供數(shù)據(jù)的遠(yuǎn)距離傳輸。底層框架如下圖:

net_device包括的信息主要有:

(1)、全局信息:設(shè)備名稱name,網(wǎng)絡(luò)設(shè)備初始化函數(shù)init()

(2)、硬件信息:共享內(nèi)在的起止地址mem_startmen_endI/O基地址base_addr,設(shè)備中斷號irq,多端口設(shè)備支持if_portDMA通道dma

(3)、接口信息:硬件頭長度hard_header_len,硬件類型type,最大傳輸單元mtu,硬件地址dev_addr,廣播地址broadcast,網(wǎng)絡(luò)接口標(biāo)志flags

(4)、設(shè)備操作函數(shù):openstopdo_ioctltx_timeoutpoll等等。

(5)、輔助成員:發(fā)送時間戳trans_start,接收時間戳last_rx,私有信息指針*priv(存放設(shè)備的一些私有信息),自旋鎖xmit_lock

四、網(wǎng)絡(luò)設(shè)備的注冊與注銷

網(wǎng)絡(luò)設(shè)備的注冊與注銷是兩個相反的過程,我們只要明白了注冊的過程那么注銷過程自然也就能明白了。網(wǎng)絡(luò)設(shè)備的注冊與注銷是使用register_netdev()unregister_netdev()這兩個函數(shù)實現(xiàn)的,這兩個函數(shù)接收的參數(shù)只有一個net_device結(jié)構(gòu)體變量,由此也可見這個結(jié)構(gòu)體就可以簡單理解成網(wǎng)絡(luò)設(shè)備,分配函數(shù)如下: alloc_netdev(sizeof(struct xxx_priv),*name,*xxx_init),三個參數(shù)分別為,私有信息結(jié)構(gòu)體的大小,設(shè)備名稱,設(shè)備初始化函數(shù)。進(jìn)一步追蹤注冊過程就是弄懂這個結(jié)構(gòu)體變量的由來,也就是分配結(jié)構(gòu)體并填充里面的成員,這就是xxx_init函數(shù)的問題了。

xxx_init函數(shù)主要完成的工作有創(chuàng)建設(shè)備的私有信息結(jié)構(gòu)體,設(shè)置設(shè)備的硬件資源(進(jìn)行硬件上的準(zhǔn)備工作),初始化設(shè)備net_device的公用成員(進(jìn)行軟件接口上的準(zhǔn)備工作),設(shè)置成員的函數(shù)指針,最后進(jìn)行私有信息的初始化。設(shè)置設(shè)備的硬件資源包括探測網(wǎng)絡(luò)設(shè)備是否存在,探測設(shè)備的具體硬件配置,申請設(shè)備所需要的硬件資源,如I/O端口,irq,DMA通道等,這個過程也可以放到設(shè)備的打開函數(shù)中來完成。

當(dāng)net_device結(jié)構(gòu)體分配并填充完后就可以調(diào)用注冊函數(shù)來注冊設(shè)備了,注銷的過程就是先調(diào)用注銷函數(shù),再釋放掉這個結(jié)構(gòu)體就行了。

五、數(shù)據(jù)的發(fā)送與接收

驅(qū)動程序調(diào)用hard_start_transmit()函數(shù)來發(fā)送數(shù)據(jù)包,這個函數(shù)在設(shè)備初始化的時候被指向了設(shè)備的xxx_tx()函數(shù)。數(shù)據(jù)的發(fā)送流程大致如下:

(1)網(wǎng)絡(luò)設(shè)備驅(qū)動程序從上層協(xié)議傳遞來的sk_buff結(jié)構(gòu)中獲取數(shù)據(jù)包的有效數(shù)據(jù)和長度,將有效數(shù)據(jù)放入臨時緩沖區(qū)。

(2)、將有效數(shù)據(jù)的長度與以太網(wǎng)數(shù)據(jù)幀的最小長度進(jìn)行比較,如果有效長度小于最小幀長,則給緩沖區(qū)末尾填充0

(3)、設(shè)置硬件的寄存器,發(fā)送時間戳,進(jìn)行數(shù)據(jù)發(fā)送的操作。

驅(qū)動的接收數(shù)據(jù)過程要依賴于中斷處理函數(shù),首先判斷中斷類型是否為接收中斷,如果是才進(jìn)行下一步接收操作。數(shù)據(jù)的接收流程大致如下:

(1)、判斷中斷類型為接收中斷后調(diào)用接收函數(shù)。

(2)、調(diào)用函數(shù)從硬件上讀取數(shù)據(jù)包長度,分配套接字緩沖區(qū)并完成協(xié)議頭的對齊操作。

(3)、讀取硬件上接收到的數(shù)據(jù),并獲取上層協(xié)議類型,將數(shù)據(jù)包遞交給上層,記錄接收時間戳,遞交上層后的操作就可以轉(zhuǎn)到去協(xié)議頭流程了。

總結(jié)

以上是生活随笔為你收集整理的网络设备驱动学习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。