第二十七篇:Windows驅動中的PCI, DMA, ISR, DPC, ScatterGater, MapRegsiter, CommonBuffer, ConfigSpace

來源:互聯網
上載者:User

標籤:defer   批量   fse   element   資料   相關   個人   映射   1.4   

近期有些人問我PCI裝置驅動的問題, 和他們交流過後, 我建議他們先看一看<<The Windows NT Device Driver Book>>這本書, 個人感覺, 這本書寫得很連貫流暢.


PCI裝置驅動基本包含了PCI的資源擷取, 配置空間的讀寫, 中斷的處理, 中斷後半部在DPC中的處理.

同一時候, 也必須瞭解DMA, ScatterGater, MapRegister, Common Buffer等基礎.


1.1 PCI裝置資源擷取

PCI裝置的資源是系統依據裝置的屬性(配置空間中寄存器的值)來動態分配的.

驅動中僅僅需在PNP START中擷取這些系統分配的資源:

比如: 筆者開發的PCI電視卡驅動中, 就使用到了當中了兩類資源, CmResourceTypePort與CmResourceTypeInterrupt.

Port地址作為裝置寄存器首地址, 之後, 能夠使用WRITE_PORT_ULONG與READ_PORT_ULONG加上對應的OFFSET來對裝置寄存器進行訪問.

Interrupt資源中解釋出來的內容, 則主要作為IoConnectInterrupt系統函數的參數, 將裝置的硬體中斷與ISR相關聯, KINTERRUPT的執行個體則是裝置中斷的軟體形式的載體.


1.2 DMA

DMA裝置, 在系統中分為MASTER與SLAVE, 另外一個非常重要的能力就是是否支援Scatter/Gather.

這些能力終於表如今DEVICE_DESCRIPTION所定義的資料結構的成員中, 比如:DmaWidth, ScatterGather, Master, Dma32BitAddresses, Dma64BitAddresses.

系統終於將各種不同類型的裝置DMA抽象為DMA_ADAPTER的執行個體, 它是裝置DMA軟體形式的載體.

驅動代碼通過IoGetDmaAdapter系統調用, 將物理裝置對象PDO與DMA描寫敘述結構作為參數, 終於得到這個DMA_ADAPTER對象, 作為興許一系列DMA相關操作的實體物件.


1.3 Map Register

使用者空間, 核心空間的虛擬記憶體與實體記憶體的關聯是通過頁表來映射的, 驅動程式猿經常會使用MDL, 它也是某一特定地區虛擬記憶體與實體記憶體的映射關係.

而DMA裝置則須要從匯流排地址(MSDN中又叫邏輯地址)與記憶體物理的映射關係角度去看待系統記憶體.

這個映射的關係就是由Map Register承擔的.

只是, 這批Map Register則依據系統而定, 有些是硬體實現, 有些是軟體中劃分出來的特定的一塊記憶體.

IoGetDmaAdapter的調用, 也是向系統申請Map Register的過程.


1.4 Common Buffer

這也是大家問得最多的問題

簡單地講, Common buffer是以DMA_ADAPTER為代表所申請的, 申請成功後, 既能通過虛擬位址訪問, 也能夠通過DMA控制器所屬邏輯地址空間的地址來訪問的連續實體記憶體.

它的優點就是物理上連續, 存在的問題是系統中連續實體記憶體是隨著系統的執行時間的流逝, 越來越稀缺.

AllocateCommonBuffer系統調用是作為DMA_ADAPTER的DmaOperations形式存在的, 所以, 詳細的一塊Common Buffer能夠說, 是與詳細的一個DMA控制器所關聯的.

AllocateCommonBuffer成功調用後, 會返回虛擬位址與DMA控制器所屬邏輯空間的邏輯地址.

筆者開發的PCI電視卡, 就是通過AllocateCommonBuffer分配一塊較小的連續實體記憶體, 用來存放Scatter/Gather列表 (某塊記憶體的邏輯地址SCATTER_GATHER_LIST.Elements[i].Address.LowPart 與該記憶體的長度SCATTER_GATHER_LIST.Elements[i].Length, 對應操作通過common buffer的虛擬位址 ).

這個Scatter/Gather List列表終於由具有S/G能力的DMA控制器來讀取(對應操作通過common buffer的邏輯地址), 依據當中的表項, 進行DMA讀/寫操作.


1.5 S/G

S/G的能力是DMA控制器的特性, 假設具有S/G的能力, 則能夠批量地DMA操作, 否則, 必須一次一次地使用MapTransfer來完畢DMA操作.

系統空間的中虛擬記憶體與實體記憶體之間的聯絡通過IoAllocateMdl與MmBuildMdlForNonPagedPool建立特定的MDL來表示.

其後,通過DMA_ADAPTER的DmaOperations中的GetScatterGatherList擷取MDL所描寫敘述的虛擬位址記憶體的S/G列表, 最後, 在GetScatterGatherList的

ExecutionRoutine 函數中, 將該列表填入Common buffer的TABLE(起始邏輯地址 與 長度)中, 以供DMA Controller所用.


1.6 ISR與DPC
剛才已經提到, ISR是通過IoConnectInterrupt注冊的.
ISR在裝置中斷到來時實調用, 但詳細的事項則交由(KeInsertQueueDpc)DPC來處理.
而DPC則是通過KeInitializeDpc系統調用, 將DPC對象KDPC與詳細的KDEFERRED_ROUTINE DPC處理函數相關聯的.

1.7 PCI裝置配置空間的訪問

其實, 普通情況下, Windows PCI裝置並不須要訪問PCI裝置配置空間.
但作為一個完整的PCI裝置驅動, 這裡提及一下.

因為PCI裝置的配置空間與IO/MEM空間是分開的, 前面已經提及IO/MEM的訪問方式, 配置空間的訪問例如以下:
定義變數:BUS_INTERFACE_STANDARD m_BusInterfaceStandard;
建立: IRP, 主與次分別為IRP_MJ_PNP, IRP_MN_QUERY_INTERFACE, 得到BUS_INTERFACE_STANDARD資料結構.
之後, 通過BUS_INTERFACE_STANDARD中的SetBusData與GetBusData來進行PCI配置空間的寄存器讀寫.

 

PCI裝置驅動全然能夠用在PCIe裝置上, 畢竟上層來講, 他們沒有太多的差別.

與USB驅動不同, PCI裝置須要考慮驅動設計中的方方面面, 希望這篇文章對大家有所借鑒作用.







第二十七篇:Windows驅動中的PCI, DMA, ISR, DPC, ScatterGater, MapRegsiter, CommonBuffer, ConfigSpace

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.