• <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>

            《WDF USB驅動開發指南》-- USB軟件結構

            PDF全文下載地址:http://download.csdn.net/source/2320280
            http://bbs.driverdevelop.com/read.php?tid-120461.html

            《USB 軟件結構 》

             

            軟件結構比硬件來的復雜很多。因為它包含了許多從表面上看不到的層次。比如總線驅動、功能驅動、過濾驅動等。套用社會學的話,這體現了功能應用中的分工和統籌。下面我們逐層來看它們。

              總線驅動
            總線驅動位于驅動棧的最低層,處理復雜的任務,必須資源分配,子設備管理。作為下層驅動,負責處理上層驅動發下來的請求。 USB 設備中的總線驅動主要有兩類:控制器驅動、 HUB 驅動;另外還有一個端口驅動。

            1 ) 控制器驅動: Ushohci.sys 、 Usbuhci.sys 、 Usbehci.sys 。

            首先解釋一下 HCI ,它是主機控制接口( Host Control Interface )的縮寫。前后一共有三種 HCI 協議出現: USB 1.1 時代,有 OHCI (開發 HCI )協議和 UHCI (通用 HCI )協議; USB2.0 時代,有 EHCI (擴展 HCI )協議。三個協議分別對應了上面的三個驅動程序。因為 USB 是向后兼容的,所以 UsbEHC.sys 中也包含了 UsbOhci 和 UsbUhci 的功能。請看下圖。

             


            圖 1 總線設備 

            上圖中設備 1 、 3 是控制器設,從名稱上就可以區別它們的不同: Universal Host Controller 和 Enhanced Host Controller 。所以設備 1 的驅動程序是 USBUhci.sys ,設備 3 的驅動程序是 USBEhci.sys 。

            這說明同一臺主機特別是筆記本電腦中, 1.1 和 2.0 的控制器并存,像筆記本電腦中的鍵盤通過內置 USB 接口與系統連接,其數據吞吐量小,只需要 1.1 的控制器就能滿足;而暴露在外供用戶使用的接口則需要 2.0 。

            2) Hub 驅動: UsbHub.sys 。 Hub 驅動是所有 USB 設備的父驅動。下圖描繪了這一景況:


            圖2


            上圖中看到, Hub 驅動的子設備要不是獨立設備,如左側圖;要么是一個含有多個子設備的父設備,如右側圖。 Hub 驅動只為直系子設備創建唯一的物理設備對象。上圖中, Hub 驅動為設備 1 和設備 2 創建物理設備對象,但并不為設備 2 的子設備創建物理設備對象。

            3 ) Port 驅動: UsbPort.sys 。這是個框架驅動,比較復雜,很少人會用到。而上面的 Ushohci.sys 、 Usbuhci.sys 、 Usbehci.sys 其實都是他的微端口驅動。對于這么偏門的框架,不提也罷。

              系統類驅動
            所以出現類驅動,體現了 USB 總線在應用上的繁榮景象。只有用得多了,才有被歸類的可能。就像人類社會中有幾百個國家,幾千個民族,正是體現了人類這個團體的多樣性與繁榮。只有在“多”的基礎上,分類才是有必要的;少數人的小群體,再怎么獨立特行,也都不足以被分類,甚至定義為“ XX 民族”。

            USB 設備包含很多的通用的功能類,比如: USB 集線器設備, USB HID 設備, USB 音頻設備, USB MIDI 設備, USB 存儲設備。為了讓開發工作變得更加簡單, Windows 操作系統為他們提供了系統驅動程序。

            大部分時候,系統類驅動就是功能驅動。下表是系統提供的 USB 類驅動。

             

            USB 類名稱
             類代碼
             驅動名稱
             系統支持
             
            藍牙設備
             0xE0
             Bthusb.sys
             Vista 、 XP
             
            USB 芯片智能卡接口設備
            (CCID)
             0x0B
             Usbccid.sys
             2K 、 XP 、 2K3 、 Vista 、 2K8
             
            Hub 設備
             0x09
             Usbhub.sys
             2K 、 XP 、 2K3 、 Vista 、 2K8
             
            HID 設備
             0x03
             Hidusb.sys
             2K 、 XP 、 2K3 、 Vista 、 2K8
             
            USB 大容量存儲設備
             0x08
             Usbstor.sys
             2K 、 XP 、 2K3 、 Vista 、 2K8
             
            打印設備
             0x07
             Usbprint.sys
             2K 、 XP 、 2K3 、 Vista 、 2K8
             
            掃描設備
             0x06
             WpdUsb.sys Usbscan.sys
             2K 、 XP 、 2K3 、 Vista 、 2K8
             
            媒體傳輸設備 (MTP)
             0x06
             WpdUsb.sys
             XP 、 2K3 、 Vista 、 2K8
             
            音頻設備
             0x01
             Usbaudio.sys
             2K 、 XP 、 2K3 、 Vista 、 2K8
             
            Modem 設備 (CDC)
             0x02
             Usbser.sys
             2K 、 XP 、 2K3 、 Vista 、 2K8
             
            視頻設備 (UVC)
             0x0E
             Usbvideo.sys
             XP 、 Vista
             

             

            表 1   系統提供的 USB 類驅動

             

            功能驅動
             

            不是所有的 USB 設備都有類驅動,但功能驅動卻是它們唯一的身份證。沒有功能驅動,設備就不足以在系統中存在。它的作用是為設備創造一個獨一無二的內核設備對象( DEVICE_OBJCET ),并因此而在需要的時候,系統能夠通過此內核設備對象找到它。

            如果要讓用戶層也能夠知道并使用 USB 設備,功能驅動更加不可少。它為設備在用戶程序可見的名字空間中,為它起一個別名,這個別名可以是一個符號鏈接,也可以是一個由 GUID 定義的設備 Interface 。通過對這個別名進行操作,也就是對設備本身進行操作。

            OK ,上面的話說得太滿了,有例外的!唯一的例外是以 RAW 模式驅動的設備。這種設備直接由總線驅動來驅動其工作,不需要功能驅動。這種例子真的不多見,也許只有很很底層的控制器設備、 Hub 設備之類,才會這樣做。對于 RAW 模式驅動的設備,當收到 IRP_MN_QUERY_CAPABILITIES 查詢請求的時候,在返回的 DEVICE_CAPABILITIES 結構體中,必須將 RawDeviceOK 位設置為 TRUE 。

            建議讀者在需要的時候使用 WinOBJ.exe 工具查看系統空間中的設備與別名。

             

            父驅動與混合設備
             

            通過一定的設置, USB 設備中的每個接口可以擁有不同的 Class 和 Protocol 定義,從而實現:一個設備,多個功能。這種設備被稱為混合設備。混合設備的前提是擁有多個接口,對單接口設備談 “ 混合 ” 是沒有意義的。

            滿足了如下兩個條件的多接口 USB 設備,被系統認為是混合設備:

            1.         設備描述符中,設備類的值為 0 : (bDeviceClass , bDeviceSubClass, bDeviceProtocol ) = (0, 0, 0);

            2.         只有唯一的配置描述符,即設備描述符中: (bNumConfigurations ) = (1)

             

            從 WinXP SP2 以后,還支持另外一種混合設備的判別方式,稱作: Interface Association Descriptor ( IAD )。其實 IAD 描述符是用來組織 “ 接口組( Interfaces Group ) ” 的。配置描述符中可以有多個 IAD 存在,如果將某兩個接口將組成接口組,那么首先這兩個接口必須是緊挨著的,其次,必須有一個 IAD 描述符位于這兩個接口描述符的前面,也必須是緊挨著的, IAD 描述符中的 bFirstInterface 用來描述接口組中的第一個接口 ID , bInterfaceCount 用來描述接口組中包含多少個接口。這樣接口集合 : [bFirstInterface, bFirstInterface+bInterfaceCount) 為一個接口組。

            當然,能夠用上 IAD 的設備,一定是有多接口存在了,否則就是多此一舉了。 IAD 描述符的識別和實現是通用父驅動完成的,所以有 IAD 支持的設備,都被認作混合設備。而識別設備是否有 IAD 支持,是通過設備描述符中的如下值判斷的:

            (bDeviceClass, bDeviceSubClass, bDeviceProtocol) = (0xEF, 0x02, 0x01)

            IAD 普及率不是很廣,一個原因就是 XP sp2 以后的操作系統版本才對它支持,這樣如果把設備插入到 Win 2000 甚至 XP SP1 上,都不能被正確識別。這樣,廠商可能必須為不同的系統寫兩套驅動程序。

            我們下面來說說當一個多接口混合設備插入電腦后,系統是如何識別它,并為它加載驅動的。這里大家要注意到一點,就是系統是如何把一個設備,通過多接口,識別為多個物理設備的。

            一開始,系統 PNP 管理器安裝常規,讀取并分析 USB 設備描述符,然后為它分配如下設備 ID :

             

            USB\VID_vvvv&PID_pppp

            USB\VID_vvvv&PID_pppp&REV_rrrr

            (vvvv, pppp, rrrr: 4 位 16 進制數,分別代表了廠商 ID ,產品 ID , USB 版本。對應于設備描述符中的這些值: idVendor/ idProduct/ bcdDevice)

             

            和兼容 ID :

             

            USB\COMPOSITE

             

            PNP 管理器首先按照常規,根據上述的設備 ID 為設備尋找合適的驅動程序:根據設備 ID 到注冊表的設備安裝信息庫(對應于 Enum 和 Class 兩個鍵)中進行搜索,如果找到了安裝記錄,就根據記錄中的信息加載驅動程序。

            問題是如果找不到合法的記錄怎么辦?這時候就用的著兼容 ID 了,兼容 ID “ USB\COMPOSITE ”是在系統中有注冊記錄的,并且就對應著通用父設備驅動( USBCCGP.sys) 。于是,系統為混合設備加載通用父設備驅動。讀者可到目錄 Windows\Inf 下查看 usb.inf 文件,此文件中包含了通用父設備驅動的安裝信息。

            通用父設備驅動通過分析配置描述符,完成兩個動作:首先為每個 USB 接口分配一個的設備 ID 和兼容 ID ;然后為每個 USB 接口創建一個物理設備對象( Physical Device Object )。設備 ID 形式如下:

             

            USB\VID_vvvv&PID_pppp&MI_mm

            USB\VID_vvvv&PID_pppp&REV_rrrr&MI_mm

            (mm: 兩個 16 位數字表示的接口號 )

             

            根據接口描述符中的 clsss 類型,分配兼容 ID ,其形式如下:

             

            USB\CLASS_cc

            USB\CLASS_cc&SUBCLASS_ss

            USB\CLASS_cc&SUBCLASS_ss&PROT_pp

            (cc/ ss / pp: 兩位 16 進制數。分別對應于接口描述符中的: bInterfaceClass/ bInterfaceSubClass/ bInterfaceProtocol)

             

            通用父設備驅動為每個接口創建了物理設備對象后,將接口的設備 ID 、兼容 ID 信息提交給 PNP 管理器, PNP 管理器就有責任為這些“虛假的”物理設備安裝驅動。仍然重復上面的過程:根據每個接口的設備 ID 和兼容 ID 在注冊表的設備安裝信息庫中搜索,試圖找到相關的安裝記錄,如果找到了,就為接口加載相應的驅動程序。如果找不到,系統就會彈出“發現新設備”的對話框,啟動驅動安裝向導。此時用戶需為這些接口手動安裝驅動。

            所以,對于多接口的混合設備( composite device ),其設備驅動的安裝分為兩個過程,先嘗試安裝混合驅動,如果找不到,就默認安裝通用父設備驅動;接下來通用父設備驅動為每個接口分配設備 ID ,并要求系統為每個接口啟動 PNP 過程。

            最后,那么來說,在 USB 混合設備中,一定是 X 個接口對應于 X 個功能設備(有一個物理設備對象)嗎?一般情況下是這樣的,但也有例外,這就是接口組:在符合一定條件的情況下,多個接口中的某些接口可以被組合為一個接口組,一個接口組代表一個功能,父設備驅動只為之創建一個物理設備對象。

            接口組的詳情,大家看后面的章節內容。

             

            過濾驅動
             

            過濾驅動無處不在。在很多時候,它被稱作 Hook ,是一種 Hack 手段;很多時候它又是必不可少的,這種技術甚至被操作系統自己使用。沒有哪一個殺防毒軟件不使用過濾驅動,我們在使用網上銀行的時候,會用到一些安全控件,基本上都借助了過濾驅動的技術。

            過濾驅動可以位于任何一層驅動的上面,或下面。過濾的對象也包括已經存在于系統中的其他的過濾驅動。當它位于某層驅動( D 驅動)上面的時候,所有目標發往 D 驅動的請求,都首先被它截取;當它位于某層驅動下面的時候,所有和 D 驅動相關的從更底層驅動反饋回來的的“完成消息”都預先被過濾驅動截取。這正是它威力強大的原因所在。對于被過濾的驅動來說,過濾驅動簡直就是它的先知了。

            但使用過濾驅動,要很慎重。很容易把系統搞得很不穩定。讀者在寫過濾驅動的時候,要明白這樣一件事:你想過濾誰,得先了解誰;好像你追求一個人,要先認識這個人。否則死機藍屏都會與你不期而遇。

             

            USB 驅動棧、設備棧
             

            請大家不要把這里的“棧”理解成“程序堆棧”的那個棧,朋友們要回到這個字最簡單的本意來理解它,而不是想象成一個數據結構。就看成草垛柴堆一樣。

            驅動棧、設備棧本質上是并行概念。驅動之間的聯系是通過設備對象進行的,所以驅動之間是間接聯系的,驅動棧多少也就只是概念上的,他用來表示一個設備能夠在系統中識別、運行,從上到下中共需要哪些驅動程序支持。

            設備棧則是由據可查的。系統中每個 DevNode 就表現一個設備棧。可以這樣理解,多個設備棧,串聯成了驅動棧。

            使用 WinDBG 的 !devnode 命令,可以列舉系統中的設備樹。下圖截取了 CY001 相關片段。

             


            圖 3 CY001 DevNode 片段 

            上圖中紅色框標出的三個 DevNode ,正好對應于三個內核驅動,建立了 CY001 的驅動棧。從上到下分別是控制器驅動 (usbEHCI) ,集線器驅動 (usbHUB) ,和功能驅動 (CY001) 。下圖以 CY001 為例,更加清晰詳細地描繪了驅動棧、設備棧的面貌。


            圖 4 CY001 的驅動棧和設備棧 

            上圖是單接口 CY001 設備的驅動棧、設備棧全圖。也適用于所有其他的單接口 USB 設備。如果是多接口混合設備,就要多一個通用父驅動,稍微復雜一點。

            最上面是可能存在的過濾驅動,因為只是“可能存在”,所以都用虛框表示。其實過濾驅動可以存在于設備棧的任何一個位置,而不僅僅是最上層。筆者不可能盡皆畫全,以上層過濾為例,能說明問題也就可以了。

            過濾驅動生成的過濾設備對象,掛載到 CY001 驅動生成的功能設備對象上;這樣所有發送給 CY001 功能設備對象的請求,過濾設備對象總是先得到。根集線器生成了 CY001 驅動的物理設備對象。三個設備連在一起,就是 CY001 驅動程序的設備棧。

            但還沒有完,根集線器驅動并不是最底層驅動,他必須得到控制器驅動的支持,于是加上可能存在的過濾驅動,由此形成中間的那條設備棧。

            仍舊未結束,控制器驅動也不是直接和系統交互的,而是通過更底層的系統總線如 PCI 、 ACPI 進行的。這樣,右側的第三條設備棧也形成了。

            由此也可以看出設備棧、驅動棧之間的關系了。驅動棧是形而上的,設備棧是形而下的。


            本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/changpei/archive/2010/05/06/5562542.aspx

            posted on 2010-11-30 10:36 wrh 閱讀(1771) 評論(0)  編輯 收藏 引用

            導航

            <2010年11月>
            31123456
            78910111213
            14151617181920
            21222324252627
            2829301234
            567891011

            統計

            常用鏈接

            留言簿(19)

            隨筆檔案

            文章檔案

            收藏夾

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            精品久久一区二区三区| 精品无码久久久久久久动漫 | 久久久久亚洲av无码专区导航| 欧美激情精品久久久久久久| 婷婷久久综合九色综合九七| 久久免费看黄a级毛片| 91精品国产乱码久久久久久| 久久精品国产99国产精品| 7777久久久国产精品消防器材| 国产精品视频久久| 天天综合久久一二三区| 久久超碰97人人做人人爱| 久久久不卡国产精品一区二区| 久久久久人妻精品一区 | 亚洲伊人久久成综合人影院 | 国产精品久久久久影视不卡| 午夜精品久久久久久| 久久99国产精品99久久| 精品国产乱码久久久久久呢| 久久99精品久久久久久水蜜桃| 精品国产乱码久久久久久呢| 久久精品国产色蜜蜜麻豆| AAA级久久久精品无码片| 成人午夜精品无码区久久| 久久久久久久亚洲精品| 办公室久久精品| 97久久精品人人做人人爽| 国内精品久久久久影院一蜜桃| 欧美激情一区二区久久久| 久久久精品波多野结衣| 亚洲国产精品久久久久婷婷老年| 午夜天堂av天堂久久久| 一本久久知道综合久久| 久久人妻无码中文字幕| 久久人人爽人人爽人人av东京热| 久久亚洲欧洲国产综合| 久久综合五月丁香久久激情| 国产视频久久| 久久se精品一区二区影院 | 18岁日韩内射颜射午夜久久成人| 人人狠狠综合久久亚洲高清|