第二十七篇:Windows驱动中的PCI, DMA, ISR, DPC, ScatterGater, MapRegsiter, CommonBuffer, ConfigSpace
2020-12-13 04:37
标签:windows pci pcie 最近有些人问我PCI设备驱动的问题, 和他们交流过后, 我建议他们先看一看>这本书, 个人感觉, 这本书写得非常连贯流畅. 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的 PCI设备驱动完全可以用在PCIe设备上, 毕竟上层来讲, 他们没有太多的区别. 与USB驱动不同, PCI设备需要考虑驱动设计中的方方面面, 希望这篇文章对大家有所借鉴作用. 第二十七篇:Windows驱动中的PCI, DMA, ISR, DPC, ScatterGater, MapRegsiter, CommonBuffer, ConfigSpace,搜素材,soscw.com 第二十七篇:Windows驱动中的PCI, DMA, ISR, DPC, ScatterGater, MapRegsiter, CommonBuffer, ConfigSpace 标签:windows pci pcie 原文地址:http://blog.csdn.net/u013140088/article/details/37742681
文章标题:第二十七篇:Windows驱动中的PCI, DMA, ISR, DPC, ScatterGater, MapRegsiter, CommonBuffer, ConfigSpace
文章链接:http://soscw.com/essay/29683.html