Tuesday, September 04, 2007

Windows Driver programming[4]

IRQ sharing

共享 IRQ 的意思就是共享 IRQ Line。共享 IRQ 的 Driver 在收到 Interrupt 的時候,得檢查這個 Interrupt 是不是自己的 Interrupt, 因為這個 Interrupt source 有可能是來自別的 Device。

Bus Master

一般而言,可以主動存取 Bus 的裝置就稱為 Bus Master。

Scatter-Gather DMA

跟 MDL 類似,當傳輸 DMA 時,可以一次傳輸不連續的 Bus address. 這個要硬體支援才行。基本上,DMA 傳輸都是連續的 Bus address。一次傳輸多筆不連續的 Bus address 資料需要額外的硬體支援。

IRP(I/O Request Packet)

IRP 的概念跟用法在 MSDN 的 Handling IRPs 一節裡有詳盡的描述。不過看得的人不是已經懂了,就是看了也不懂。我儘量寫的清楚一點。

IRP( I/O Request Packet),顧名思義,就是一個要求做 IO 的封包。那為甚麼文件寫的這麼複雜?因為 WDM driver 是屬於疊疊樂型的, 所以會變成你的 Driver 的上方還有許多 Driver,下方也有很多 Driver。

如果你的 Driver 需要對 Device 做 IO 的話,因為 Driver 並沒有直接面對硬體(下面還有許多 Driver!),所以變成你得透過這些 Driver 幫你轉送這些 IRP 才能把你要的轉給 Device。 並且因為 Driver 的種類太多了,MS 無法為每種 Driver 定 IRP 的 routing 架構,所以只好訂出一般化的 IRP routing 方式,而後果就是,很多名詞變得很抽象,入門者光看這些名稱根本無法瞭解文件在寫甚麼。

但是這樣做好處太多了:
  • 你可以在 Driver 上下插入 Driver,監控進出的 IRP。不爽還可以偷偷把 IRP 幹掉。

壞處就是,架構變得很複雜,跟效能的損失。

而處理 IRP 變成 Driver 最最重要的部份,光是需要注意的便有: Synchronous/Asynchronous IRP、IRP 的配置、IRP 的傳送、取消 IRP、釋放 IRP 等工作。

Synchronous and Asynchronous IRP

IRP 只有一種,就是 IRP。會有 Synchronous 跟 Asynchronous 之分,是源自於 IRP 傳送的方式。

如果你寫過 Socket 程式,那你應該會知道 Asynchronous I/O 跟 Synchronous I/O 的概念。簡言之,便是 Synchronous IRP 一傳送,Driver 就得等這個 IRP 完成才能夠繼續執行, 而 Asynchronous IRP 會繼續執行下去。這個考量在 User mode Application 當然沒問題(其實還是會有啦,不然不會有一堆 Asynchronous API 出來), 只要把這些東西放到 Thread 內,然後再用一些同步機制就可以搞定。

但是這一招在 Driver 裡面是不行的,Windows Driver 裡有定義每個函式能夠執行的 IRQL,而跑在 Dispatch Level 之上的 thread,是不能夠使用 Synchronous IRP 的,因為它們不可以睡覺,而 Synchronous IRP 會讓該 thread 去睡覺。

使用 Asynchronous IRP 也有很大的困擾:同步的問題。在 Driver 裡面同步可不比 Application mode,一不小心就 BSOD 了,麻煩。另外,Asynchronous IRP 必須在 Driver 內部配置跟釋放,而 Synchronous IRP 則是 Driver 配置,系統(I/O manager)釋放。

No comments:

codeblock