共用方式為


DMA 驗證

DMA 驗證會監視使用直接記憶體存取 (DMA) 。 由於 DMA 常式隨著 Windows 開發而變更,因此許多驅動程式都會不正確的使用 DMA 呼叫。 此外,某些驅動程式寫入器會嘗試完全略過 HAL DMA 子系統。 此做法可以在驅動程式中引入不具弱點的 Bug。

驅動程式驗證器的 DMA 驗證選項會嘗試攔截常見的 DMA 錯誤。 除了 !dma 核心偵錯工具延伸模組之外,它可以用來確認驅動程式是否以適當的方式使用 DMA。

此驅動程式驗證器選項也稱為 HAL 驗證。 驅動程式驗證器所產生的一些錯誤訊息可能會使用此詞彙。

不同類型的 DMA

DMA 是一種機制,可讓硬體裝置在不使用處理器的情況下,將資料傳送至記憶體或從記憶體傳輸。 需要處理器才能設定傳輸,裝置會在完成傳輸時發出處理器的訊號。 此系統的優點是處理器可以在執行 DMA 傳輸時執行其他工作。

Windows 2000 和更新版本中使用數種類型的 DMA:

Common-buffer DMA
當系統可以配置硬體和軟體可存取的單一緩衝區時,就會執行通用緩衝區 DMA。 驅動程式負責同步處理對緩衝區的存取。 不會快取記憶體,讓驅動程式更容易進行這項同步處理。 設定通用緩衝區之後,驅動程式和硬體都可以直接寫入緩衝區中的位址,而不需要 HAL 介入。

封包 DMA
當有單一現有的緩衝區必須對應以供硬體使用時,就會執行封包 DMA。 使用封包 DMA 的範例是將檔案從記憶體傳輸到磁片。 在此情況下,使用 Common-buffer DMA 會很浪費,因為必須先將檔案傳輸至通用緩衝區,硬體才能將它傳送至磁片。 相反地,會諮詢 HAL;它會提供驅動程式所需的資訊,以協助硬體在記憶體中尋找實際的緩衝區。 這項作業很複雜,需要涉及的常式跨不同架構運作。

散佈圖/收集 DMA
散佈/收集 DMA 是一種快捷方式方法,一次設定數個封包 DMA 傳輸。 例如,如果您要透過網路傳輸封包,網路堆疊的每個部分都會 (TCP、IP、乙太網路等) 新增自己的標頭。 這些標頭全都配置自記憶體中不同位置。 在此情況下,散佈圖/收集 DMA 可藉由發出批次要求給 HAL 來對應每個標頭以及硬體存取的資料區段來節省時間。 此方法不需要在封包的每個部分呼叫封包 DMA 常式,而是呼叫每個常式一次,並讓 HAL 負責個別對應每個常式。

注意散佈/收集功能 並不表示裝置可以使用散佈/收集常式。 散佈/收集功能是指裝置描述中的旗標,指出裝置可以從記憶體中的任何區域讀取或寫入,而不只是特定範圍。

系統 DMA
系統 DMA 是透過將主機板上的系統 DMA 控制器程式設計為直接進行傳輸來執行。 只有 ISA 卡片可以使用系統 DMA。

DMA 驗證的效果

當 DMA 驗證作用中時,驅動程式驗證器會偵測 DMA 常式的誤用,包括:

  • 硬體或驅動程式) 可能會造成這些錯誤的超溢或不足 (這些錯誤。

  • 按兩下通用緩衝區、配接器通道、地圖暫存器或散佈/收集清單。

  • 未釋放常見的緩衝區、配接器通道、地圖暫存器、散佈/收集清單或配接器,以流失記憶體。

  • 一次有多個介面卡通道可供配接器使用。

  • 嘗試使用已釋放且已不存在的配接器。

  • 未排清配接器緩衝區。

  • 配接器的未處理參考計數太多。

  • 在可分頁緩衝區上執行 DMA, (所有緩衝區都應該在 DMA 傳輸開始) 之前鎖定。

  • 在具有管理旗標的 MDL 上執行 DMA。

  • 參考不正確系統位址、第一個 MDL 之前或第一個 MDL 結尾之後,或使用超過 MDL 緩衝區的傳輸長度,並跨越 MDL 內的分頁界限。

  • 一次配置太多對應暫存器,或配置比允許的最大數目更多的對應暫存器。

  • 對應暫存器雙對應。

  • 嘗試釋放地圖暫存器,但有些暫存器仍會進行對應。

  • 嘗試排清尚未對應的對應暫存器。

  • 嘗試在對應暫存器檔案結尾排清太多位元組。

  • 在不正確的 IRQL 呼叫 DMA 常式。

  • 將 null 值DMA_ADAPTER傳遞至 HAL 常式。

  • 當地址未包含在 MDL 中時,將位址和 MDL 傳遞至 HAL 常式。

  • 嘗試對應已經對應的位址範圍。

  • 嘗試清除未對應的緩衝區。

  • 嘗試對應長度為零的緩衝區以進行傳輸。

  • 呼叫過時函式 HalGetAdapter (所有驅動程式都必須改用 IoGetDmaAdapter) 。

驅動程式驗證程式會監視驅動程式的行為,並在發生這些違規時0xE6問題檢查。 如需錯誤檢查參數的清單 ,請參閱錯誤檢查0xE6 (DRIVER_VERIFIER_DMA_VIOLATION) 。

DMA 驗證何時有用?

呼叫 HAL DMA 常式來直接 (使用 DMA 的所有驅動程式,) 都應該使用 DMA 驗證進行測試。

此外,也應該測試迷你埠驅動程式,因為它們通常會藉由呼叫使用 DMA) 的埠驅動程式,間接使用 DMA (。

DMA 驗證也可以是偵測記憶體損毀的有效方式,因為它可以在驅動程式或硬體裝置滿溢 DMA 緩衝區時發現。

監視 DMA 驗證

核心偵錯工具延伸模組 !dma 可用來顯示豐富的 DMA 資訊。 它可以顯示每個 DMA 配接器行為的各種詳細資料。 !dma延伸模組的詳細範例,以及偵錯工具延伸模組的一般資訊,請參閱 Windows 套件偵錯工具中的檔。 如需詳細資訊 ,請參閱 Windows 偵錯

啟用此選項

您可以使用驅動程式驗證器管理員或Verifier.exe命令列,為一或多個驅動程式啟用 DMA 驗證功能。 如需詳細資訊,請參閱 選取驅動程式驗證器選項

  • 在命令列

    在命令列中,DMA 驗證選項是以 位 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
    
  • 使用驅動程式驗證器管理員

    1. 啟動驅動程式驗證器管理員。 在命令提示字元視窗中輸入 驗證程式
    2. 選取 [為程式碼開發人員) 建立自訂設定 ( ],然後按 [ 下一步]。
    3. 從完整清單中選取 [選取個別設定]。
    4. 選取 [ (檢查 DMA 驗證) 。

    DMA 驗證功能也會包含在標準設定中。 若要使用此功能,請在驅動程式驗證器管理員中,按一下 [建立標準設定]。