青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

S.l.e!ep.¢%

像打了激速一樣,以四倍的速度運轉,開心的工作
簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

NDIS網絡驅動程序編程要點 [轉]

Posted on 2009-02-22 23:10 S.l.e!ep.¢% 閱讀(849) 評論(0)  編輯 收藏 引用 所屬分類: Windows WDM

網絡驅動程序編程要點

編寫 Windows 2000 的任何網絡驅動程序時通常都需要考慮的幾點問題

1 可移植性

2 多處理器支持

3 IRQLs

4 同步和指示

5 包結構

6 使用共享內存

7 異步I/O和完成函數

?

1. 可移植性

NDIS 驅動程序應很容易在支持 Windows 2000 的平臺間移植。一般說來,從一個硬件平臺移植到另一個平臺只需要將它在兼容系統的編譯中重新編譯即何。

驅動程序開發者應當避免調用與操作系統相關的函數,因為這將使他們的驅動程序不可移植。應用 NDIS 函數替換這些調用,只調用 NDIS 函數將使代碼在支持 NDIS 的微軟操作系統中可移植, NDIS 為編寫驅動程序提供了很多支持函數,并且直接調用操作系統是不需要的。

驅動程序應用 C 來編寫。更近一步,驅動程序代碼應當限制在 ANSI C 標準并且應當避免使用不被其他兼容系統編譯器支持的語言特性。驅動程序代碼編寫不應當使用任何 ANSI C 標準指明為“ implementation defined” 的特性來編寫。

驅動程序應當避免使用任何在不同平臺上大小和結構變化的數據類型,驅動程序代碼不應該調用任何 C 的運行時庫函數,而是限于調用 NDIS 提供的函數。

在內核模式下漂移指針是不允許的。試圖運行這樣的操作將是一個致命的錯誤。

如果驅動程序代碼要支持特殊平臺的特性,那么這些代碼應當包含在 #ifdef #endif 聲明之間。

2 . 多處理器支持

編寫的代碼應當可以在多處理器系統中安全運行。這對于編寫可移植的 Windows 2000 驅動程序是很重要的。一個網絡驅動程序必須使用 NDIS 函數庫提供的多處理器安全保證。

在單處理器環境下,在一個時刻單處理器只運行一條機器指令,既使這樣,當包到達或時間中斷發生時,對于NIC或其他設備執行的中斷也可能發生。典型的,當正在操縱數據結構時,例如它的隊列時,驅動程序對NIC發出停用中斷來操縱數據,隨后再發生可用中斷。許多線程在單處理器環境下表現的好像是在同一時刻運行的,但是實際上它們卻是在獨立的時間片上運行的。

在多處理器環境下,處理器同時可運行多條機器指令,一個驅動程序必須異步化,這使得當一個驅動程序函數正在操縱一個數據結構時,同樣的在其他處理器運行的驅動程序函數不能修改共享的數據。在一個SMP機器中,所有的驅動程序代碼都要重新裝入,為了消除這種資源保護問題,Windows 2000驅動程序使用自旋鎖。

3. IRQL

所有 NDIS 調用的驅動程序函數都運行在系統決定的 IRQL 下, PASSIVE_LEVEL<DLSPATCH_LEVEL<DIRQL 中的一個。例如,一個微端口初始化函數、掛起函數、重啟函數和有時的關閉函數通常都運行在 PASSIVE_LEVEL 下。中斷代碼運行在 DIRQL 下,所以 NDIS 中層或協議驅動程序從不運行在 DIRQL 下。所有其他的 NDIS 驅動程序函數運行在 IRQL<=DISPATCH_LEVEL 下。

驅動程序函數運行于的 IRQL 將影響調用什么樣的 NDIS 函數。特定的函數只可在 IRQL PASSIVE_LEVEL 下調用,其他的函數可在 DISPATCH_LEVEL 或更低層調用。一個驅動程序的編寫者應當檢查每一個 NDIS 函數的 IRQL 限制。

任何與驅動程序的 ISR 共享資源的驅動程序函數必須能將它的 IRQL 升級到 DTRQL 來防止爭用情況的發生, NDIS 提供了這種機質。

4. 同步和指示

當兩個線程共享可被同時訪問的資源時,無論是單處理機還是 SMP ,同步是必須的。例如,對于一個單處理機,如果一個驅動程序正在訪問一個共享資源時,被一個運行在更高 IRQL (例如 ISR )的函數中斷時,必須保護共享資源以阻止這種爭用的發生而使資源處于不確定狀態。在一個 SMP 中,兩個線程可以在同一時刻運行,在不同處理器上并且試圖來修改同一數據的訪問必須同步。

NDIS 提供了自旋鎖可以用來對在同一 IRQL 下運行的線程間訪問共享資源實現同步。當兩個線程在不同 IRQL 下訪問共享資源時, NDIS 提供了一種機制來臨時 高低 IRQL 代碼的 IRQL ,以使得訪問共享資源串行化。

??? NDIS提供下面四種機制來保證同步:

自旋鎖

自旋鎖提供了一個用來保護共享資源的同步機制,這種資源是單處理器或一個多處理機下的、運行在 IRQL>PASSIVE_LEVEL 下的、內核模式中的線程所共享使用的。一個自旋鎖在同時運行在一個 SMP 機上不同的執行線程之間提供同步。一個線程在訪問保護資源前獲得一個自旋鎖。自旋鎖使得任務線程中只有持有自旋鎖的線程可使用資源。一個等待自旋鎖的線程將在試圖獲得鎖時間內循環,直到持有鎖的線程釋放為止。

??? 自旋鎖還存在著一個不太明顯但很重要的事實:你僅能在低于或等于 DISPATCH_LEVEL 級上請求自旋鎖,在你擁有自旋鎖期間,內核將把你的代碼提升到 DISPATCH_LEVEL 級上運行。在內部,內核能在高于 DISPATCH_LEVEL 的級上獲取自旋鎖,但你和我都做不到這一點。 KeAcquireSpinLock 獲取自旋鎖時,它會把 IRQL 提升到 DISPATCH_LEVEL 級上。當 KeReleaseSpinLock 釋放自旋鎖時,它會把 IRQL 降低到原來的 IRQL 級上。如果你知道代碼已經處在 DISPATCH_LEVEL 級上,你可以調用兩個專用函數來獲取自旋鎖。 KeAcquireSpinLockAtDpcLevel KeReleaseSpinLockFromDpcLevel 。一個編寫很好的網絡驅動程序應該會減少自旋鎖持有的時間。

??? 一個典型的使用自旋鎖的例子是保護一個隊列。例如,微端口發送函數MiniportSend將協議驅動程序傳來的包進行排隊。因為其他驅動程序函數也使用這個隊列,MiniportSend必須用一個自旋鎖保護這個隊列使得在一個時刻只有一個線程可操縱這個隊列。Miniport Send獲得自旋鎖,添加包到隊列后釋放自旋鎖。使用自旋鎖保證持鎖線程是唯一修改隊列的線程,同時使得包被安全地添加到隊列中。當NIC驅動程序從隊列中取走包時,通過同樣的自旋鎖保護這個訪問。當執行指令修改隊列頭或任何隊列組成域時,驅動程序必須用自旋鎖保護隊列。

避免死鎖問題

Windows 2000 并不限制網絡驅動程序同時持有多于一個的自旋鎖。但是,驅動程序的某部分在持有自旋鎖 B 時,試圖獲得自旋鎖 A ,并且其他部分在持有鎖 A 時,試圖獲得自旋鎖 B 時,死鎖就會發生。如果要獲得多于一個的自旋鎖,驅動程序應當通過強制以某一順序獲得鎖來避免死鎖,這就是說,如果一個驅動程序強制在獲得自旋鎖 A 之后才可獲得鎖 B ,那么上述情況就不會發生。

總得來說,使用自旋鎖將對系統性能帶來負面效應,所以驅動程序不應當使用許多鎖。

時鐘

時鐘被用來輪詢或進行超時操作的。一個驅動程序可以產生一個時鐘并與一個函數關聯上。當一個特定周期時鐘期滿時,調用相關函數。時鐘可以是一次的或周期性的,一但設置了一個周期時鐘,當每個周期結束時都會觸發,直到它被完全清除掉為止。一次性時鐘在觸發后必須重新設置。

時鐘通過調用 NdisMInitializeTimer 來產生和初始化,并且通過調用 NdisMsetTimer 來設置,也可調用 NdisMsetPeriodicTimer 設置周期時鐘。如果使用了一個非周期時鐘,那么通過調用 NdisMSetPeriodicTimer 重新設置時鐘。通過調用 NdisMCancelTimer 可以清除時鐘。

事件

事件在兩個執行線程之間實現同步操作。一個事件通過一個驅動程序裝入并且通過調用 NdisInitializeEvent 初始化。一個運行在 IRQL PASSIVE_LEVEL 下的線程調用 NdisWaitEvent 來將自身轉入等侯狀態。當一個驅動程序線程等待一個事件時,它指定了最大等待時間即等待事件的時間。當調用 NdisSetEvent 使時間得到信號量,或最大等待時間段結束時,它們兩個無論是誰先發生時都將結束線程等待狀態。

典型的,事件是通過相互協調的線程調用 NdisSetEvent 來設置的。事件被創建時是沒有信號量的,但為了指示等待線程,它必須要設置信號量,事件將一直處于保持有信號狀態,直到 NdiResetEvent 調用后為止。

5. 包結構

通過一個協議驅動程序可以分配NDIS包、填充數據,并且將它傳遞到下層的NDIS驅動程序,以便將數據發送到網絡上。一些最底層的NIC驅動程序分配包用來保存接收到的數據,并將包傳遞到對應的高層驅動程序。有時,一個協議驅動程序分配一個包,并且通過一個請求將它傳給NIC驅動程序,以使NIC驅動程序將接收到的數據拷貝到提供的包中。NDIS提供函數用來分配和操縱構成包的子結構。

包描述符

Flags physicallPageCount

ToralLenth FirstBuffer P

緩存描述符:

StartVirtualAddress P

ByteOffset ByteCount PhysicalPage [] Next P....

?

緩存

?

緩存描述符:

StartVirtualAddress P

ByteOffset ByteCount PhysicalPage [] Next P....

?

虛擬內存

虛擬頁

虛擬頁

虛擬頁

虛擬頁

虛擬頁

物理內存

物理頁

物理頁

物理頁

物理頁

物理頁


1NDIS包結構

具體詳情可以參考:http://www.ndis.com/papers/ndispacket/ndispacket1.htm

6 . 使用共享內存

??? 用作總線管理DMA設備的微端口驅動程序必須為NICNIC驅動程序分配共享內存。當在一個驅動程序和它的NIC之間共享cache時,特別的預防是必須的。在某種結構下,必須采取特別步驟來保證內存一致,因為NIC可以直接訪問共享的物理內存,而NIC驅動程序卻要通過cache訪問內存。這就引起驅動程序和NIC訪問內存的不同,即使它們看起來在同一位置。

7. 異步I/O和完成函數

因為在一些網絡操作中有繼承的因素,許多由 NIC 驅動程序提供的上層函數和協議驅動程序提供的下層函數被設計成支持異步操作,而不是用 CPU 消耗一定時間的循環來等待一個任務的完成或硬件事件的指示,網絡驅動程序依賴處理許多異步操作的能力。

通過使用完成函數來支持異步網絡 I/O 。以下的例子將說明網絡的 send 操作如何使用一個完成函數,同樣的機制也存在一個協議或 NIC 驅動程序的其他操作中。

當協議驅動程序調用 NDIS 發送一個包時, NDIS 調用 NIC 驅動程序的 MiniportSend 函數發送請求, NIC 驅動程序試圖立即完成這個請求并且返回一個恰當的狀態值。對于 步操作,可能返回 NDIS_STATUS_SUCCESS 作為發送成功的標志, NDIS_STATUS_RESOURCES NDIS_STATUS_FAILURE 表明有某些失敗。

但是一個發送操作要花費一些時間來完成,此時 NIC 驅動程序 ( NDIS) 可將包排隊并且等侯 NIC 指示發送操作的結果。 NIC 驅動程序的 MiniportSend 函數可以通過返回一個 NDIS_STATUS_PENDING 的狀態值來異步處理這個操作,當 NIC 驅動程序完成了發送操作后,包調用完成函數 NdisMSendComplete 在調用中傳遞指向一個已被發送的包的描述符的指針。這個信息會傳給協議驅動程序,指示完成了操作。

許多需要一定時間來完成的驅動程序操作用完成數來完成支持異步的操作。這種函數有同一形式的名字 NidisMXxxComplete 。不僅可用于發送和接收函數,完成函數也可用于查詢、配置、重新設置硬件、狀態指示、指示收到數據和傳送收到數據。

?

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            另类尿喷潮videofree| 欧美国产日韩一区| 韩国一区电影| 国产欧美日本| 国产视频亚洲| 在线观看精品一区| 亚洲免费成人| 亚洲欧美一区二区原创| 久久福利一区| 亚洲国产精品久久久久秋霞影院| 免费久久久一本精品久久区| 欧美激情亚洲另类| 在线中文字幕一区| 久久精品91久久久久久再现| 欧美福利网址| 国产精品日本| 亚洲精品麻豆| 久久久噜噜噜久久| 日韩一级成人av| 久久精品五月| 欧美特黄一级大片| 亚洲电影免费观看高清完整版在线观看 | 亚洲日本成人网| 亚洲午夜电影网| 久久青青草原一区二区| 亚洲精品久久久久久下一站 | 久久精品国产亚洲a| 亚洲福利视频在线| 亚洲免费在线精品一区| 欧美成年网站| 黑人巨大精品欧美一区二区| 中文久久乱码一区二区| 免费观看在线综合色| 中日韩男男gay无套| 免费观看在线综合| 国产一区二区中文| 亚洲夜间福利| 亚洲乱码国产乱码精品精| 久久人91精品久久久久久不卡 | 国产精品视频导航| av成人国产| 亚洲黄色在线视频| 久久亚洲欧美国产精品乐播| 国产农村妇女毛片精品久久莱园子 | 亚洲乱码精品一二三四区日韩在线| 香蕉久久精品日日躁夜夜躁| 欧美日韩一区在线播放| 亚洲精品国精品久久99热一| 麻豆91精品| 久久精品免视看| 狠狠爱www人成狠狠爱综合网| 欧美亚洲三区| 亚洲先锋成人| 国产精品日本| 久久精品国产一区二区三区免费看| 亚洲一区二区三区三| 欧美日韩日本网| 一本不卡影院| 日韩午夜免费| 欧美天堂亚洲电影院在线播放| 99热在线精品观看| 亚洲精品之草原avav久久| 欧美日韩大陆在线| 亚洲一级网站| 午夜精品免费视频| 国产视频久久网| 久久久噜噜噜久久| 久久亚洲私人国产精品va| 浪潮色综合久久天堂| 国内精品模特av私拍在线观看| 久久成人一区二区| 久久国产精品毛片| 亚洲国产mv| 日韩视频免费大全中文字幕| 欧美图区在线视频| 欧美有码在线视频| 久久激情五月激情| 日韩一级精品| 亚洲欧美国产不卡| 亚洲电影免费观看高清完整版| 亚洲国产日韩一区二区| 国产精品久久久久久模特| 久久高清福利视频| 久久伊人免费视频| 亚洲视频第一页| 性色av一区二区怡红| 亚洲精品一区在线观看香蕉| 一区二区三区导航| 激情成人av| 一本综合久久| 影音先锋另类| 亚洲最快最全在线视频| 国模一区二区三区| 亚洲裸体视频| 在线不卡中文字幕| 中文av一区二区| 激情六月婷婷久久| 一区二区三区精品视频在线观看| 国产一区二区三区电影在线观看| 亚洲大胆女人| 国产日韩欧美一区二区| 亚洲国产一区二区三区a毛片| 国产精品亚洲精品| 亚洲日本久久| 亚洲国产第一页| 亚洲欧美999| 一二三四社区欧美黄| 久久久久综合一区二区三区| 亚洲天堂网在线观看| 麻豆成人在线| 久久久一二三| 国产农村妇女毛片精品久久麻豆 | 欧美一级日韩一级| 欧美日本一区二区高清播放视频| 久久国产一区二区三区| 欧美三级电影网| 欧美激情亚洲| **性色生活片久久毛片| 欧美尤物巨大精品爽| 亚洲欧美中文日韩在线| 欧美日韩ab片| 91久久精品美女高潮| 一色屋精品视频免费看| 欧美在现视频| 欧美专区在线播放| 国产精品羞羞答答xxdd| 这里只有精品视频| 亚洲天堂av综合网| 欧美日韩高清在线| 最新日韩在线| 亚洲精选成人| 欧美激情综合色| 91久久精品www人人做人人爽| 欧美一级电影久久| 欧美亚洲一区三区| 欧美午夜精品理论片a级按摩| 亚洲国产精品99久久久久久久久| 亚洲大片一区二区三区| 久久精品三级| 老司机免费视频一区二区三区| 国产在线观看91精品一区| 欧美一区二区免费| 久久野战av| 亚洲国产精品电影| 欧美成人午夜剧场免费观看| 亚洲大片一区二区三区| 亚洲裸体俱乐部裸体舞表演av| 欧美精品久久久久久久免费观看| 亚洲激情视频在线播放| 日韩视频在线一区二区| 欧美午夜电影一区| 香蕉久久夜色精品国产| 狂野欧美一区| 夜夜爽www精品| 国产嫩草影院久久久久 | 欧美大胆人体视频| 一本久道久久久| 久久精品国产99| 91久久在线| 国产精品成人免费| 久久精品官网| 亚洲区中文字幕| 性做久久久久久久免费看| 韩国精品在线观看| 欧美人妖在线观看| 欧美一进一出视频| 亚洲高清三级视频| 欧美一级网站| 亚洲精品日韩在线| 国产欧美一区二区三区久久人妖 | 亚洲欧美日韩一区二区在线| 久久网站免费| 亚洲深夜福利网站| 精东粉嫩av免费一区二区三区| 欧美激情a∨在线视频播放| 亚洲专区一二三| 欧美激情一区二区三区高清视频| 亚洲摸下面视频| 亚洲国产精品黑人久久久| 国产精品一区二区在线观看不卡 | 亚洲国产成人高清精品| 欧美一级久久| 99精品欧美| 伊人成人在线视频| 国产精品乱码| 欧美精品一卡| 久久久夜精品| 欧美在线观看www| 亚洲伦理久久| 亚洲二区在线观看| 狼狼综合久久久久综合网| 亚洲一区二区视频在线| 最近中文字幕日韩精品| 狠狠干成人综合网| 国产精品一区二区a| 欧美精品一区二区三区在线看午夜| 欧美专区18| 午夜亚洲影视| 亚洲欧美激情一区二区| 在线一区二区三区四区五区|