Windows之磁碟的裝置驅動堆疊

來源:互聯網
上載者:User

 磁碟的裝置驅動堆疊

本文節選自《Windows 核心情景分析--採用開原始碼ReactOS》一書

     讀者已經在前幾節中看到,裝置的驅動常常分成“類裝置驅動”和“連接埠裝置驅動”兩層。例如滑鼠器就成為一個裝置的類,而具體又有PS/2滑鼠器、串口滑鼠器以及基於USB的HID滑鼠器,所以滑鼠器的驅動就分為一種類裝置驅動和三種連接埠裝置驅動。其中PS/2滑鼠器的連接埠驅動是直接與硬體打交道的。不過連接埠驅動也可能不直接驅動硬體,而只是對虛擬硬體進行操作。HID滑鼠器的連接埠驅動就是這樣,因為它與實際的硬體之間還隔著USB匯流排這一層,因而需要把HID的連接埠裝置驅動堆疊在USB匯流排驅動的上面,USB匯流排驅動下面又是USB的類驅動和連接埠驅動。至於類裝置驅動與連接埠裝置驅動之間的關係,則既可以是一對一的,也可以是一對多的。
     類裝置驅動與連接埠裝置驅動的劃分有三方面的好處。一方面,像滑鼠器驅動那樣,可以把不同種類滑鼠器驅動中的公用部分抽取出來,避免開發滑鼠器驅動時的重複勞動。這種重複勞動不僅是浪費的問題,而且還容易引起差錯和不相容。另一方面,即使實際上某種裝置並不成為“類”,把本來可以是“整塊式”的裝置驅動按其邏輯和機理分成兩塊也有好處,因為那樣可以增進軟體的模組化,從而使這些模組的來源多樣化。再說,類裝置驅動與連接埠裝置驅動的劃分,以及這二者在介面介面形式上的規範性,還使得按需要在二者之間插入“過濾”模組成為可能。
    所以類裝置驅動與連接埠裝置驅動的劃分是個重要的概念,也是一項重要的技術。
     但是,就磁碟的驅動而言,類驅動和連接埠驅動的分離仍舊是不充分的,因為磁碟有邏輯和物理之分,邏輯磁碟很可能就是物理磁碟上的一個分區,還可能實際上不是磁碟。所以,在這樣的條件下,還會把類驅動再分成兩層,成為上下兩個裝置對象,上面的稱為“功能(性)裝置驅動(Functional Device Object)”即FDO,下面的稱為“物理裝置驅動(Physical Device Object)”即PDO。不過PDO未必就是直接與物理裝置打交道的裝置對象,而是(向上)代表著某種物理裝置的裝置對象,“代表著”不一定就是“直接操作著”。有時候,FDO和PDO實際上就只是“上、下”之分。那麼,連接埠裝置驅動是否還可以進一步分解呢?
     對於同一種裝置,來自不同廠家的硬體介面也會有些不同,但是這種不同只是局部的、少量的,一般都集中在底層直接與硬體有關的地方,而離具體的硬體介面稍遠就又都一樣了。以磁碟為例,首先“Block Storage裝置”形成一個類,屬於這個類的有磁碟、磁帶、光碟片,可能還有隨身碟、Ramdisk等。而磁碟又有邏輯和物理之分。因為一個物理的磁碟可以分成好幾個分區,而每個分區就是一個邏輯的磁碟。然後,物理的磁碟又有IDE磁碟和SCSI磁碟之分。最後,即使同為IDE磁碟,不同廠家的產品也會有些不同和特殊之處,例如IDE介面的寄存器可以表現在只能通過in、out指令訪問的I/O地址空間,也可以表現在通過mov指令訪問的記憶體位址空間;有些廠家還提供IDE磁碟陣列,有些則可能還有特殊的操作要求等。如果要求每個磁碟廠家都必須提供全套的驅動即整個磁碟驅動堆疊,那當然不現實。即使只要求提供整個連接埠驅動,那也會造成許多重複開發,並且也對磁碟廠家提出了更高的要求,增加了許多負擔。而如果能把其中公用的部分提取出來,做成一個共用的模組,使磁碟廠家可以只做與具體產品密切相關的那一部分驅動程式,那麼磁碟廠家的負擔就可以降到最低。這就是Miniport驅動的由來,Mini既有“小”的意思,也有“最小化(Minimalized)”的意思。而提取出來的公用部分,則仍稱為Port驅動,本質上就是作業系統核心的一部分,所以一般是由微軟自己提供的。“Miniport”這個詞,按字面意義稱之為“小連接埠”或“最小連接埠”固然可以,但也不盡合適,因為沒有反映出這種驅動模組的本質;筆者覺得稱之為“末梢連接埠”或許還可以,因為Miniport都是在最底層直接與硬體打交道的。
    再看上下層裝置對象之間的介面。在“類驅動+連接埠驅動”的模型中,二者之間的介面就是常規的由IRP和IoCallDriver()所構成的介面。當然,載運在IRP上的資料或資料結構是根據具體情況而定的,這需要上下兩個模組之間有個協議。而若把類驅動分為FDO和PDO兩層,則兩層之間的互動一般遠較類驅動與連接埠驅動之間的互動更為複雜和緊密,此時光靠由IRP和IoCallDriver()構成的介面就不夠了。為此,在類驅動的FDO和PDO之間往往有另外一個介面,要由下層向上層提交一個資料結構,通過該資料結構向上層“登記”有關的函數指標和資料。可是這樣一來又有了問題,因為下層驅動模組的裝入理應在上層模組之前,既然如此,那下層模組又如何向尚未裝入的上層模組登記呢?於是,FDO中又得劃分出一部分,這一部分是需要在下層模組之前裝入的,起著PDO與FDO之間的中介作用,使下層模組在初始化時可以預先登記。這一部分當然是個可以獨立裝入的模組,但是卻不建立自己的裝置對象,因為它的裝置對象(如果要說實質上有的話)就是其所屬的類驅動的裝置對象,要到裝入時才會建立。如果我們以是否有裝置對象為依據把裝置驅動模組分成“有形”和“無形”兩種,那麼這就是屬於無形的裝置驅動模組。就其本質而言,無形的驅動模組就相當於系統空間的DLL,實質上成為核心的擴充。此外,應用軟體在開啟某個裝置時只能以(有命名的)裝置對象為目標,所以無形的驅動模組不能作為應用軟體的開啟目標。
    實際上,從類驅動中劃分出一個無形的模組並不只是為瞭解決下層模組(PDO)向上層登記的問題,這裡面也有“提取公因子”的問題。比方說,磁碟本身構成一類裝置即磁碟類,但是同時它又屬於一個更大的類即Block Storage裝置類;而磁帶類同樣也屬於Block Storage裝置類。這二者顯然存在著一些共性。如果分別加以實現,則磁碟的類驅動和磁帶的類驅動中勢必有一部分程式是共同的。既然有共同的部分,那就不如把它提取出來。事實上,classpnp.sys就是從Windows的Block Storage裝置的類驅動中抽取出來的公用部分。
    類似的原理也適用於連接埠驅動與小連接埠驅動之間,這二者的裝置對象之間的介面既保留了IRP+ IoCallDriver(),又增加了基於由下層向上層“登記”的擴充介面。
    所以,Windows的這個以IRP和IoCallDriver()為特徵的模型,簡潔固然是簡潔,實際上卻並不能貫徹始終,對於比較複雜的裝置就不能愉快勝任了。而由下層向上層登記一個資料結構,以提供函數指標和資料,則正是Linux所採用的方法。
    可以這樣來理解,基於IRP和IoCallDriver()的裝置對象堆疊構成特定裝置驅動的骨架,體現著總體上的層次關係;但是此骨架中的某些層次又可以進一步劃分成“子層”,子層之間的介面並不完全遵循Irp+IoCallDriver()的模型。不過,“過濾驅動(Filter Driver)”只能插入在堆疊中的骨幹層次之間。
    下面介紹SCSI磁碟(不包括光碟片)驅動的堆疊,但是我們把注意力集中在堆疊的構成以及類、連接埠、小連接埠驅動的相互關係,而不是集中在具體的操作細節上,因為許多細節是因具體硬體而異的。我們假定所用的是SCSI磁碟,而插在電腦匯流排上的介面即“適配器(Adapter)”,是Adaptec的1540B介面板。DDK提供了這種介面板的小連接埠驅動,但是卻並未提供SCSI的連接埠驅動,所以下面的有些代碼取自DDK,有些卻取自ReactOS。而在類驅動這一層上,DDK倒是既提供了disk.sys的代碼,也提供了classpnp.sys的代碼。
對於SCSI磁碟,其驅動模組堆疊的構成為:
    disk.sys。這是磁碟的類驅動,分為FDO和PDO兩個子層,這兩個子層各有自己的裝置對象。二者的結合把對於邏輯磁碟的操作映射到對於物理磁碟的操作。如前所述,磁碟和磁帶等同屬於Block Storage裝置類,所以部分本來可以放在disk.sys中的公用代碼被提取了出來,成為classpnp.sys。DDK提供了這個模組的源碼。
    classpnp.sys。這是個無形的模組,沒有自己的裝置對象,只是起著函數庫的作用。DDK提供了這個模組的源碼。
    scsiport.sys。SCSI磁碟的連接埠驅動,這又是個無形的模組,沒有自己的裝置對象。DDK並未提供這個模組的源碼,但是ReactOS已經實現了這個模組。
    aha154x.sys。這是Adaptec 1540B介面板的小連接埠驅動。DDK提供了這個模組的源碼。
    disk.sys和classpnp.sys這兩個驅動模組合在一起相當於一個類驅動模組,可是分成兩塊以後稱為什麼呢?在DDK的源碼中,前者的路徑是src/storage/class/disk,似乎應該算是類驅動;可是後者既然名為classpnp.sys,就更應該是類驅動。然而,這二者的特性顯然不同,前者是有形的,其所建立的裝置對象在裝置對象堆疊中,而後者只是個無形的函數庫,可見微軟對於什麼樣的驅動是類驅動並無明確的定義。不過,從後面的代碼中可以看出,如果把classpnp.sys理解成對於“塊裝置”這個大類的驅動,而把disk.sys理解成對於“磁碟”這個子類的驅動,則也還可以說得通。
    現在我們可以讀代碼了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.