天天看點

如何在WDM中使用xp系統的DMA用來處理資料

     最近做了一款pci的視訊采集卡(h264壓縮),由于資料傳輸量比較大,所有想采用dma來傳輸資料,剛開始感覺很簡單,後來感覺還是困難重重。

        dma 驗證監控直接記憶體通路 (dma) 的使用。随着 windows 的開發,dma 例程已經發生改變,是以許多驅動程式錯誤地使用了 dma 調用。而且,一些驅動程式作者嘗試完全繞過 hal dma 子系統。這種做法可能将隐含的錯誤引入驅動程式。

驅動程式驗證程式的 dma 驗證選項嘗試捕獲常見的 dma 錯誤。與 !dma 核心調試程式擴充一起使用時,可以驗證驅動程式是否在以适當的方式使用 dma。

此驅動程式驗證程式選項也稱為“hal 驗證”。驅動程式驗證程式生成的一些錯誤消息可能使用此術語。

此驅動程式驗證程式選項僅在 windows xp 及更高版本中提供。

dma 是一種機制,硬體裝置通過該機制可以與記憶體互傳資料,而無需使用處理器。設定傳輸需要使用處理器,并且在裝置完成傳輸時會向處理器發送信号。此系統的優勢在于,在執行 dma 傳輸時處理器可以執行其他任務。

windows 2000 及更高版本中使用了若幹類型的 dma。

<dl></dl>

<dt>通用緩沖區 dma</dt>

<dd></dd>

當系統可以配置設定硬體和軟體都能通路的單個緩沖區時,将執行通用緩沖區 dma。驅動程式負責對緩沖區的同步通路。不緩存記憶體,這使得驅動程式執行此同步更友善。在設定通用緩沖區之後,驅動程式和硬體都可以直接寫入緩沖區中的位址,而無需 hal 的任何幹預。

<dt>資料包 dma</dt>

如果存在一個現有的單一緩沖區,并且必須映射該緩沖區才能供硬體使用,将執行資料包 dma。使用資料包 dma 的示例是從記憶體到磁盤傳輸檔案。在此情況下使用通用緩沖區 dma 是一種浪費,因為需要将檔案傳輸到通用緩沖區,硬體才能将其傳輸到磁盤。這時可借助 hal;它可以為驅動程式提供所需的資訊,幫助硬體查找記憶體中的實際緩沖區。此操作比較複雜,因為需要涉及一些例程跨不同體系結構執行操作。

<dt>分散/集中 dma</dt>

分散/集中 dma 是一次設定若幹資料包 dma 傳輸的快捷方法。例如,如果通過網絡傳輸資料包,網絡資料包的每部分都會添加自己的标頭(tcp、ip、以太網等)。這些标頭都從記憶體中的不同位置配置設定。在此情況下,使用分散/集中 dma 可以節省時間,該方法通過将批處理請求發送到 hal 來映射每個标頭和資料段以供硬體通路。此方法無需在資料包的每個部分上調用資料包 dma 例程,而是對每個例程調用一次,并讓 hal 負責分别映射它們。

note  分散/集中功能并不意味着裝置可以使用分散/集中例程。分散/集中功能在裝置描述中引用一個标志,該标志訓示裝置可以從記憶體中的任何區域讀寫,而不隻是特定範圍。

<dt>系統 dma</dt>

系統 dma 的執行方式是在主機闆上對系統 dma 控制器進行程式設計以直接執行傳輸。隻有 isa 卡可以使用系統 dma。

當 dma 驗證處于活動狀态時,驅動程式驗證程式檢測 dma 例程的錯誤使用情況,其中包括:

dma 記憶體緩沖區過載或不足(這些錯誤可能由硬體或驅動程式造成)。

雙重釋放通用緩沖區、擴充卡通道、映射系統資料庫或分散/集中清單。

由于不釋放通用緩沖區、擴充卡通道、映射系統資料庫、分散/集中清單或擴充卡而導緻記憶體洩漏。

一次對一個擴充卡提供多個擴充卡通道。

嘗試使用已被釋放且不複存在的擴充卡。

不重新整理擴充卡緩沖區。

一個擴充卡的未處理引用計數太多。

在可分頁緩沖區上執行 dma(在開始 dma 傳輸之前應鎖定所有緩沖區)。

在具有已損壞标志的 mdl 上執行 dma。

在第一個 mdl 之前或第一個 mdl 結束之後引用無效的系統位址,或者使用的傳輸長度超過 mdl 緩沖區并超過 mdl 中的頁面邊界。

一次配置設定的映射系統資料庫太多,或者配置設定的映射系統資料庫超過允許的最大數。

對映射系統資料庫進行雙重映射。

系統資料庫仍在映射時就嘗試釋放映射系統資料庫。

嘗試重新整理尚未映射的映射系統資料庫。

在映射系統資料庫檔案末尾嘗試重新整理的位元組數太多。

在不正确的 irql 上調用 dma 例程。

将 null 值 dma_adapter 傳遞到 hal 例程。

在位址未包含在 mdl 中時,将該位址和 mdl 傳遞到 hal 例程。

嘗試映射已經映射的位址範圍。

嘗試重新整理尚未映射的緩沖區。

嘗試為傳輸映射零長度緩沖區。

直接使用 dma 的所有驅動程式(通過調用 hal dma 例程)都應使用 dma 驗證測試。

此外,還應測試微型端口驅動程式,因為它們通常間接使用 dma(通過調用使用 dma 的端口驅動程式)。

dma 驗證還可以作為檢測記憶體損壞的有效方法,因為它可以檢測到是驅動程式還是硬體裝置造成了 dma 緩沖區溢出。

核心調試程式擴充 !dma 可用于顯示大量的 dma 資訊。它可以顯示有關每個 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 驗證功能還包括在标準設定中。要使用此功能,請在驅動程式驗證程式管理器中單擊“建立标準設定”。

繼續閱讀