如何在WDM中使用xp係統的DMA用來處理數據
最近做了一款pci的視頻采集卡(H264壓縮),由於數據傳輸量比較大,所有想采用dma來傳輸數據,剛開始感覺很簡單,後來感覺還是困難重重。
DMA 驗證監控直接內存訪問 (DMA) 的使用。隨著 Windows 的開發,DMA 例程已經發生改變,因此許多驅動程序錯誤地使用了 DMA 調用。而且,一些驅動程序作者嚐試完全繞過 HAL DMA 子係統。這種做法可能將隱含的錯誤引入驅動程序。
驅動程序驗證程序的 DMA 驗證選項嚐試捕獲常見的 DMA 錯誤。與 !dma 內核調試程序擴展一起使用時,可以驗證驅動程序是否在以適當的方式使用 DMA。
此驅動程序驗證程序選項也稱為“HAL 驗證”。驅動程序驗證程序生成的一些錯誤消息可能使用此術語。
此驅動程序驗證程序選項僅在 Windows XP 及更高版本中提供。
不同類型的 DMA
DMA 是一種機製,硬件設備通過該機製可以與內存互傳數據,而無需使用處理器。設置傳輸需要使用處理器,並且在設備完成傳輸時會向處理器發送信號。此係統的優勢在於,在執行 DMA 傳輸時處理器可以執行其他任務。
Windows 2000 及更高版本中使用了若幹類型的 DMA。
- 通用緩衝區 DMA
-
當係統可以分配硬件和軟件都能訪問的單個緩衝區時,將執行通用緩衝區 DMA。驅動程序負責對緩衝區的同步訪問。不緩存內存,這使得驅動程序執行此同步更方便。在設置通用緩衝區之後,驅動程序和硬件都可以直接寫入緩衝區中的地址,而無需 HAL 的任何幹預。
- 數據包 DMA
-
如果存在一個現有的單一緩衝區,並且必須映射該緩衝區才能供硬件使用,將執行數據包 DMA。使用數據包 DMA 的示例是從內存到磁盤傳輸文件。在此情況下使用通用緩衝區 DMA 是一種浪費,因為需要將文件傳輸到通用緩衝區,硬件才能將其傳輸到磁盤。這時可借助 HAL;它可以為驅動程序提供所需的信息,幫助硬件查找內存中的實際緩衝區。此操作比較複雜,因為需要涉及一些例程跨不同體係結構執行操作。
- 分散/集中 DMA
-
分散/集中 DMA 是一次設置若幹數據包 DMA 傳輸的快捷方法。例如,如果通過網絡傳輸數據包,網絡數據包的每部分都會添加自己的標頭(TCP、IP、以太網等)。這些標頭都從內存中的不同位置分配。在此情況下,使用分散/集中 DMA 可以節省時間,該方法通過將批處理請求發送到 HAL 來映射每個標頭和數據段以供硬件訪問。此方法無需在數據包的每個部分上調用數據包 DMA 例程,而是對每個例程調用一次,並讓 HAL 負責分別映射它們。
Note 分散/集中功能並不意味著設備可以使用分散/集中例程。分散/集中功能在設備描述中引用一個標誌,該標誌指示設備可以從內存中的任何區域讀寫,而不隻是特定範圍。
- 係統 DMA
-
係統 DMA 的執行方式是在主板上對係統 DMA 控製器進行編程以直接執行傳輸。隻有 ISA 卡可以使用係統 DMA。
DMA 驗證的效果
當 DMA 驗證處於活動狀態時,驅動程序驗證程序檢測 DMA 例程的錯誤使用情況,其中包括:
-
DMA 內存緩衝區過載或不足(這些錯誤可能由硬件或驅動程序造成)。
-
雙重釋放通用緩衝區、適配器通道、映射注冊表或分散/集中列表。
-
由於不釋放通用緩衝區、適配器通道、映射注冊表、分散/集中列表或適配器而導致內存泄漏。
-
一次對一個適配器提供多個適配器通道。
-
嚐試使用已被釋放且不複存在的適配器。
-
不刷新適配器緩衝區。
-
一個適配器的未處理引用計數太多。
-
在可分頁緩衝區上執行 DMA(在開始 DMA 傳輸之前應鎖定所有緩衝區)。
-
在具有已損壞標誌的 MDL 上執行 DMA。
-
在第一個 MDL 之前或第一個 MDL 結束之後引用無效的係統地址,或者使用的傳輸長度超過 MDL 緩衝區並超過 MDL 中的頁麵邊界。
-
一次分配的映射注冊表太多,或者分配的映射注冊表超過允許的最大數。
-
對映射注冊表進行雙重映射。
-
注冊表仍在映射時就嚐試釋放映射注冊表。
-
嚐試刷新尚未映射的映射注冊表。
-
在映射注冊表文件末尾嚐試刷新的字節數太多。
-
在不正確的 IRQL 上調用 DMA 例程。
-
將 Null 值 DMA_ADAPTER 傳遞到 HAL 例程。
-
在地址未包含在 MDL 中時,將該地址和 MDL 傳遞到 HAL 例程。
-
嚐試映射已經映射的地址範圍。
-
嚐試刷新尚未映射的緩衝區。
-
嚐試為傳輸映射零長度緩衝區。
-
調用過時函數 HalGetAdapter(所有驅動程序必須改用 IoGetDmaAdapter)。
驅動程序驗證程序監控驅動程序的行為,如果發生其中的任意衝突,將發送錯誤檢查 0xE6。有關錯誤檢查參數列表,請參閱 Bug Check 0xE6 (DRIVER_VERIFIER_DMA_VIOLATION)。
何時使用 DMA 驗證?
直接使用 DMA 的所有驅動程序(通過調用 HAL DMA 例程)都應使用 DMA 驗證測試。
此外,還應測試微型端口驅動程序,因為它們通常間接使用 DMA(通過調用使用 DMA 的端口驅動程序)。
DMA 驗證還可以作為檢測內存損壞的有效方法,因為它可以檢測到是驅動程序還是硬件設備造成了 DMA 緩衝區溢出。
監控 DMA 驗證
內核調試程序擴展 !dma 可用於顯示大量的 DMA 信息。它可以顯示有關每個 DMA 適配器行為的各種詳情。Windows 程序包的調試工具文檔中提供了 !dma 擴展的詳細示例以及有關調試程序擴展的常規信息。有關詳細信息,請參閱 Windows 調試。
激活此選項
通過使用驅動程序驗證程序管理器或 Verifier.exe 命令行,可以為一個或多個驅動程序激活 DMA 驗證功能。使用命令行
-
在命令行,DMA 驗證選項由 Bit 7 (0x80) 表示。要激活 DMA 驗證,請使用標誌值 0x80 或將 0x80 添加到該標誌值。例如:
- verifier /flags 0x80 /driver MyDriver.sys
該功能將在下次啟動時激活。
在 Windows Vista 及更高版本的 Windows 上,還可以通過將 /volatile 參數添加到此命令激活和停用 DMA 驗證而不用重啟計算機。例如:
- verifier /volatile /flags 0x80 /adddriver MyDriver.sys
此設置將立即生效,但在關閉或重啟計算機時將丟失。有關詳細信息,請參閱 使用易失性設置。
DMA 驗證功能還包括在標準設置中。例如:
- verifier /standard /driver MyDriver.sys
-
使用驅動程序驗證程序管理器
- 啟動驅動程序驗證程序管理器。在“命令提示符”窗口中鍵入 Verifier。
- 選擇“創建自定義設置(供程序開發人員使用)”,然後單擊“下一步”。
- 選擇“從一個完整的列表選擇單個設置”。
- 選擇(選中)“DMA 驗證”。
DMA 驗證功能還包括在標準設置中。要使用此功能,請在驅動程序驗證程序管理器中單擊“創建標準設置”。
最後更新:2017-04-03 16:48:45