加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

在PCIE linux内核驱动程序中流式传输DMA

发布时间:2020-12-14 01:51:13 所属栏目:Linux 来源:网络整理
导读:我正在研究用于 Linux内核的FPGA驱动程序.代码似乎在x86上工作正常,但在x86_64上我遇到了一些问题.我实现了流式DMA.所以它就像 get_user_pages(...);for (...) { sg_set_page();}pci_map_sg(); 但pci_map_sg返回的地址如0xbd285800,没有通过PAGE_SIZE对齐,所
我正在研究用于 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事务列表.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读