我在 32 位 Windows 7 环境中遇到了 PCI Express 板的问题。该板是一个音频/视频捕获设备,可对 32 个独立的标清模拟视频通道执行实时 H.264 编码。它使用 DMA 将压缩帧传送到 Win7 主机驱动程序。
在系统启动时,板卡驱动程序使用 DmaAdapter 对象的 AllocateCommonBuffer 函数从非分页池中分配 DMA 缓冲区。缓冲区必须全部位于相同的 256MB 物理地址范围内才能映射到板。当 win7 主机系统启动时,这个分配总是成功的。
除了简单的引导加载程序外,该板没有任何常驻固件;它需要在应用程序运行时将固件映像(通过驱动程序)下载到板上。但是,作为此固件下载过程的一部分,Windows 应用程序必须通过驱动程序发出 BOARD_RESET ioctl 以使电路板进入已知状态。不幸的是,当板子收到重置命令时,它会短暂地从 win7 PnP 管理器的视图中“消失”,它认为发生了 SURPRISE_REMOVAL 事件。随后,板驱动程序被迫将其所有分配的 DMA 缓冲区释放回非分页池,并等待来自 PnP 管理器的 StartDevice 事件。
当接收到下一个 StartDevice 事件时,板卡驱动程序无法再完成 DMA 分配。由于碎片,它无法从非分页池中找到足够的缓冲区来映射到相同的物理地址范围。驱动程序使 StartDevice 事件失败,然后由 PnP 管理器从服务中删除。
我正在寻找针对这种情况的编程解决方法。是否可以在板重置期间以某种方式暂停设备节点,因此 PnP 管理器不会将其检测为移除?是否有可以覆盖设备移除检测的 PnP 配置?有什么办法可以挂在驱动程序第一次启动时成功获取的 DMA 缓冲区上?有没有办法在非分页池中保留页面范围供该驱动程序使用?DMA 缓冲区相当大:200 个缓冲区,每个 634880 字节,它们都必须来自相同的 256MB 范围(即,在 0x10000000 边界上)。我有板驱动程序的完整源代码,可以进行任何必要的修改;它是从供应商处购买的参考设计的一部分。这是我第一次接触 Windows 设备驱动程序。