<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 高性能路由器硬件抽象層的關(guān)鍵技術(shù)研究

高性能路由器硬件抽象層的關(guān)鍵技術(shù)研究

作者: 時(shí)間:2009-09-29 來(lái)源:網(wǎng)絡(luò ) 收藏

  1 引 言

  隨著(zhù)Internet的飛速發(fā)展和寬帶技術(shù)的不斷出現,骨干核心的體系結構也發(fā)生了一些變化。近年來(lái),高性能體系結構的研究和國內外主流廠(chǎng)商生產(chǎn)的大部分商用高端的實(shí)現方案中,普遍采用了集中式交換、分布式報文處理和轉發(fā)的體系結構[1,2]。

  文獻[3]提出了(Hardware AbstractionLayer,HAL)的設計思想,成功地解決了分布式路由器面臨的通用性支撐軟件系統結構設計問(wèn)題,為構建開(kāi)放通用的路由器軟件基礎平臺提供了保證。包括虛擬驅動(dòng)、系統管理和內部通信3大模塊,在整個(gè)路由器系統中的位置如圖1所示。

路由器系統

  結合國家863重大課題“高性能IPv6路由器基礎平臺及實(shí)驗系統”,將文獻[3]中提出的在嵌入式操作系統Hard HatLinux中進(jìn)行了實(shí)現。本文針對高性能路由器體系結構的特點(diǎn),研究了硬件抽象層在實(shí)現過(guò)程中的關(guān)鍵技術(shù)。主要包括虛擬驅動(dòng)的動(dòng)態(tài)加載模式、基于分隔符的TCP傳輸方法、基于地址映射的內核態(tài)與用戶(hù)態(tài)間的阻塞式數據交換機制幾個(gè)內容。

  2 支撐軟件在高性能IPv6路由器中實(shí)現的關(guān)鍵技術(shù)

  2.1 虛擬驅動(dòng)的動(dòng)態(tài)加載模式

  虛擬驅動(dòng)模塊是模擬線(xiàn)路接口單元動(dòng)作的重要部分,他的靈活性和可擴展性直接影響硬件抽象層的可用性。

  在Linux操作系統下,該模塊是作為一個(gè)內核模塊來(lái)實(shí)現的。他可以實(shí)現動(dòng)態(tài)加載,與靜態(tài)加載相比具有很大的靈活性。編譯時(shí),內核模塊可單獨進(jìn)行模塊的編譯調試,縮短了調試時(shí)間;使用時(shí),將該模塊鏈接到內核,便可發(fā)揮模擬線(xiàn)路接口單元的作用;擴展或升級時(shí),可以將其卸載后進(jìn)行修改。除此之外,動(dòng)態(tài)加載還可以縮減Linux內核的大小,使編譯后的內核小巧,占用內存較少,提高了運轉速度。

  2.2 基于地址映射的內核態(tài)與用戶(hù)態(tài)間的阻塞式數據交換機

  Linux操作系統中的進(jìn)程分為用戶(hù)態(tài)進(jìn)程和內核態(tài)進(jìn)程2類(lèi),用戶(hù)態(tài)進(jìn)程不能直接執行運行在內核態(tài)的內核代碼或者存取操作系統內核的數據結構。在內存管理方面,Linux系統采用虛擬內存管理機制,設置了兩級頁(yè)表結構,通過(guò)頁(yè)面地址和在該頁(yè)中的偏移量就可以惟一確定虛擬地址所對應的物理地址。

  在硬件抽象層的實(shí)現中,內部通信處于用戶(hù)態(tài),虛擬驅動(dòng)處于內核態(tài)。而他們之間不可避免地需要進(jìn)行一些數據的傳遞,即處于Linux 不同空間的2個(gè)進(jìn)程要進(jìn)行通信。但是,這2個(gè)模塊分處于Linux系統的用戶(hù)空間和內核空間,數據指針如何傳遞是一個(gè)問(wèn)題,指針傳遞后如何映射又是一個(gè)問(wèn)題。因此用戶(hù)態(tài)與內核態(tài)之間內存地址的傳遞和轉換成為了提高硬件抽象層工作效率的關(guān)鍵。

  2.2.1 內核態(tài)與用戶(hù)態(tài)的指針傳遞

  先來(lái)解決內存地址的傳遞問(wèn)題,根據Linux驅動(dòng)程序的特點(diǎn),選擇ioctl()函數來(lái)傳遞指針。該函數屬于系統調用,調用后將一個(gè)類(lèi)型為ifreq的結構指針變量ral_ifr從用戶(hù)態(tài)傳入內核態(tài),該結構的定義在/include/linux/if.h中。

  使用了其中的ifrn_name和ifru_data兩個(gè)域,其中ifrn_name代表設備的名稱(chēng),即虛擬接口設備名,ifru_data為所要傳遞的數據指針。使用系統調用ioctl()之后,用戶(hù)空間到內核空間的指針傳遞就完成了。內核空間到用戶(hù)空間的指針傳遞過(guò)程與其相反。因此,下一步要進(jìn)行的是內核空間與用戶(hù)空間數據指針的映射。

  2.2.2 內核態(tài)與用戶(hù)態(tài)的內存映射

  由2.2.1可知,用戶(hù)空間的指針通過(guò)ioctl傳入內核空間后,他本身并沒(méi)有發(fā)生改變,需要進(jìn)行虛擬地址到物理地址的映射才可以對其進(jìn)行讀寫(xiě)操作。

  由文獻[4]分析可知,可以使用內核kiobuf機制,他能提供從內核空間對用戶(hù)內存的直接訪(fǎng)問(wèn)。內核kiobuf機制的設計初衷就是為了便于將用戶(hù)空間的緩沖區映射到內核。使用他能夠獲得數據的頁(yè)面起始位置、頁(yè)數和偏移量等具體參數,因此可在內核空間對用戶(hù)態(tài)申請的內存進(jìn)行操作。

  首先分配一個(gè)內核I/O向量(kiovec)來(lái)產(chǎn)生kiobuf,使用函數如圖2所示。

使用函數

  然后再對其進(jìn)行初始化,如圖3所示。

初始化

  最后,將通過(guò)ioctl傳入的用戶(hù)空間指針ifru_data映射到內核態(tài),使用函數map_user_kiobuf,如圖4所示。

映射到內核態(tài)

  這樣就完成了將指針由用戶(hù)空間映射到內核空間的過(guò)程,實(shí)現了從虛擬地址向物理地址的轉換。

  至此,內核空間與用戶(hù)空間的內存映射問(wèn)題得到了很好的解決。通過(guò)解決內存地址映射的問(wèn)題,內部通信和虛擬驅動(dòng)之間就可以只傳遞數據指針,大大提高了模塊的運行效率。

  2.3 基于分隔符的TCP實(shí)時(shí)傳輸方法

  2.3.1 Nagle算法的弊端

  糊涂窗口綜合癥(Silly WindowSyndrome)的出現使開(kāi)銷(xiāo)過(guò)大,從而造成TCP性能變壞。根據文獻[5]所述,糊涂窗口綜合癥的解決方法就是采用文獻[6]中所建議的Nagle算法。但是在實(shí)際應用時(shí)發(fā)現,Nagle算法的不足之處主要有2點(diǎn):

  (1)在限制數據報頭部信息消耗的帶寬總量的同時(shí),是以犧牲網(wǎng)絡(luò )延遲為代價(jià)的。

  (2)在發(fā)送方的緩沖區中,應用程序發(fā)送的數據包發(fā)生了粘滯的現象,即發(fā)送的若干數據包到接收方接收時(shí)變成一包,分不出各個(gè)包的界線(xiàn)。

  前者因為數據被排隊而不是立即發(fā)送的,因此不適用于需要快速響應時(shí)間的系統。后者則會(huì )影響到接收方的數據處理的準確性。第一種不足可以通過(guò)使用PUSH標記來(lái)實(shí)現,發(fā)送方如果使用了該標志,會(huì )立即將緩沖區中的數據發(fā)送出去。對于第二個(gè)問(wèn)題,解決起來(lái)就比較復雜,因為出現數據包粘滯現象的原因既可能由發(fā)送方造成,也可能由接收方造成。

  2.3.2 基于分隔符的TCP實(shí)時(shí)傳輸方法

  采用了基于分隔符的TCP實(shí)時(shí)傳輸方法來(lái)解決包粘滯問(wèn)題。該方法在應用層數據包的起始部分附加上有特定格式的分隔符和數據長(cháng)度域,其中分隔符用于界定數據包之間的界限,長(cháng)度域則用于表示該數據包的實(shí)際長(cháng)度。

  首先,所有經(jīng)內部通信模塊傳輸的數據,都需要進(jìn)行一次內部固定格式的封裝。封裝后數據包的包頭,是由內部通信模塊自定義的,起始位置是分隔符和長(cháng)度域。其次,接收方按照內部通信模塊的自定義的包結構,接收后對數據流進(jìn)行預處理,還原成為應用程序可正確識別的數據包。預處理的原理如下:先查找包頭中的分隔符,他標識著(zhù)一個(gè)數據包的開(kāi)始;接下來(lái)的域表示的是實(shí)際數據包的長(cháng)度len,取出緊跟在包頭后的長(cháng)度為len的那段數據,這就是需要應用程序處理的數據包。

  包粘滯的情況具體可細分為3大類(lèi),這里均以2個(gè)應用程序數據包粘滯成一段的情況為例,如圖5~圖9所示,當應用程序數據包個(gè)數為n時(shí),可采用類(lèi)似的方法進(jìn)行處理。

包粘滯的情況

包粘滯的情況

包粘滯的情況

包粘滯的情況

包粘滯的情況

  第1類(lèi),粘滯數據是由完整的數據包組成的,如圖5所示。這種情況的處理非常簡(jiǎn)單,按分隔符找到數據包的起始位置,再根據數據長(cháng)度取出應用程序數據即可。

  第2類(lèi),粘滯數據是由完整數據包和應用程序數據殘缺的數據包組成,如圖6和圖7所示。處理時(shí),需要對殘缺數據包2的應用程序數據部分進(jìn)行保存,內部通信包頭的數據長(cháng)度域也要記錄下來(lái),以便下次接收時(shí)知道應用程序數據剩余部分的長(cháng)度。再次收到數據時(shí),就根據剩余長(cháng)度取出一段數據,與上次保存的應用程序數據合為一個(gè)完整的數據包。

  第3類(lèi),粘滯數據是由完整數據包和內部通信包頭殘缺的數據包組成,如圖8和圖9所示。首先,要將如圖8所示數據段中收到的殘缺的這部分包頭保存起來(lái),然后收取下一次數據如圖9所示。再從收取的數據中,截取可以與上次殘缺包頭組成完整的內部通信包頭的一段報文,形成所需要的內部通信包頭。當然,該段數據有可能并不是內部通信包頭,這可以從分隔符是否正確等內部通信封裝格式來(lái)判斷。如果發(fā)生這種情況,就要將指針以字節為單位,順次向后滑動(dòng),直到找到真正的內部通信包頭為止。然后根據包頭中的信息,取出相應長(cháng)度的應用程序數據交送給應用程序接收者。

  解決了上述分析的2大不足之后,內部通信模塊中實(shí)現的TCP傳輸,在保證數據傳輸的良好的可靠性和流控性之外,還具備了一定的實(shí)時(shí)性能和防止數據包粘滯的功能。

  3 結 語(yǔ)

  本文研究了硬件抽象層在高性能IPv6路由器實(shí)現中的關(guān)鍵技術(shù),主要分析了虛擬驅動(dòng)的動(dòng)態(tài)加載模式、基于分隔符的TCP實(shí)時(shí)傳輸方法、基于地址映射的內核態(tài)與用戶(hù)態(tài)間的阻塞式數據交換機制。通過(guò)上述關(guān)鍵技術(shù)的研究,使硬件抽象層得以實(shí)時(shí)、高效地運行,并且已穩定運行于高性能IPv6 路由器中。



評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>