【问题标题】:Writing a Windows 64-bit device driver for a 32-bit PCI device为 32 位 PCI 设备编写 Windows 64 位设备驱动程序
【发布时间】:2012-12-01 16:49:09
【问题描述】:

我正在评估将我几年前编写的设备驱动程序从 32 位移植到 64 位。物理设备是 32 位 PCI 卡。也就是说,该设备是 32 位的,但我需要从 Win7x64 访问它。该设备向 Windows 世界提供一些寄存器,然后执行繁重的总线主控数据传输到一块驱动程序分配的内存中。

我在 Microsoft 文档中读到,您可以指示驱动程序是否支持 64 位 DMA。如果不是,则 DMA 是双缓冲的。但是,我不确定是否是这种情况。我的驱动程序将/可能是一个完整的 64 位驱动程序,因此它可以支持处理器地址空间中的 64 位地址,但实际的物理设备不支持它。事实上,设备 BAR 必须映射到 4 GB 以下,并且设备必须获得一个 PC RAM 地址才能执行 4 GB 以下的总线主控。这是否意味着我的驱动程序将始终通过双缓冲?这是一个对性能非常敏感的过程,双缓冲可能会阻止整个系统工作。

当然,设计新的 64 位 PCI(或 PCI-E)板是不可能的。

任何人都可以为这个过程提供一些资源(除了 MS 页面)吗?

非常感谢!

【问题讨论】:

    标签: windows 64-bit driver dma pci


    【解决方案1】:

    为仅支持 32 位 PCI 寻址的设备编写 64 位驱动程序没有问题。正如 Alexey 所指出的,您创建的 DMA 适配器对象指定了您设备的硬件寻址能力。当您分配 DMA 缓冲区时,操作系统会考虑到这一点,并确保在您的硬件可访问区域内分配这些缓冲区。 Linux 驱动程序的行为类似,您的驱动程序必须提供一个 DMA 地址掩码以与您的设备相关联,稍后使用的 DMA 函数将引用该掩码。

    如果您的应用程序分配了一个需要进行 DMA 存取的缓冲区,您可能会遇到性能损失。这个缓冲区可以分散在整个内存中,内存中的页面超过 4G。如果您的驱动程序计划对这些进行 DMA,则需要在 DMA 期间将缓冲区页面锁定在 RAM 中,并根据页面位置为您的 DMA 引擎构建一个 SGL。问题是,对于 4G 以上的页面,操作系统必须将它们复制/移动到 4G 以下的页面,以便您的 DMA 引擎能够访问它们。这就是潜在的性能损失所在。

    【讨论】:

      【解决方案2】:

      这是一个旧帖子,我希望答案仍然相关......

      这里有两部分,PCI target 和 PCI master access。

      PCI 目标访问: 驱动程序将 PCI BAR 映射到 64 位虚拟地址空间,驱动程序只需通过指针读取/写入。

      PCI主访问:您需要通过调用IoGetDmaAdapter()创建一个DmaAdapter对象。创建时,您还描述了您的设备是 32 位的(请参阅 DEVICE_DESCRIPTION 参数)。然后调用DmaAdapter::AllocateCommonBuffer() 方法在PC RAM 中分配一个连续的DMA 缓冲区。

      我不确定双缓冲。根据我的经验,不使用双缓冲,而是 DmaAdapter::AllocateCommonBuffer() 如果无法分配满足 DEVICE_DESCRIPTION 的缓冲区(在您的情况下为 32 位 dma 寻址),则会失败。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-20
        • 2010-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-11
        • 2011-09-03
        相关资源
        最近更新 更多