gpt4 book ai didi

linux - PCIE linux 内核驱动程序中的流式 DMA

转载 作者:IT王子 更新时间:2023-10-29 00:56:55 24 4
gpt4 key购买 nike

我正在为 Linux 内核开发 FPGA 驱动程序。代码似乎在 x86 上运行良好,但在 x86_64 上我遇到了一些问题。我实现了流式 DMA。就这样

get_user_pages(...);
for (...) {
sg_set_page();
}
pci_map_sg();

但是 pci_map_sg 返回了类似 0xbd285800 的地址,这些地址没有按 PAGE_SIZE 对齐,所以我无法发送完整的第一页,因为 PCIE规范说

"Requests must not specify an Address/Length combination which causes a Memory Space access to cross a 4-KB boundary."

有什么方法可以对齐地址,还是我错过了一些重要的东西?

Source code of DMA .

最佳答案

第一个想到的可能性是进入的用户缓冲区不是从页面边界开始的。如果您的起始地址是整个页面的 0x800 字节,那么您的第一个 sg_set_page 调用的偏移量将为 0x800。这将产生一个以 0x800 结尾的 DMA 地址。这是正常情况,不是错误。

由于 pci_map_sg 合并页面,第一个片段可能比一页大。重要的是 pci_map_sg 生成连续的 DMA 可寻址内存块,但它不生成低级 PCIe 事务列表。在 x64 上,您更有可能获得较大的区域,因为大多数 x64 平台都有 IOMMU。

我处理的许多设备都有 DMA 引擎,允许我指定几兆字节的逻辑传输长度。通常,PCIe 端点中的 DMA 实现负责在每个 4kB 边界开始一个新的 PCIe 事务,程序员可以忽略该约束。如果 FPGA 中的资源太有限而无法处理,您可以考虑编写驱动程序代码以将 Linux 内存块列表转换为(更长的)PCIe 事务列表。

关于linux - PCIE linux 内核驱动程序中的流式 DMA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9381571/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com