- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在使用高速串行卡将数据从外部源高速传输到带有 PCIe 卡的 Linux 机器。 PCIe 卡带有一些第 3 方驱动程序,这些驱动程序使用 dma_alloc_coherent 分配 dma 缓冲区以接收数据。然而,由于 Linux 的限制,此方法将数据传输限制为 4MB。我一直在阅读并尝试多种分配大型 DMA 缓冲区的方法,但一直无法使一种方法起作用。
这个系统有 32GB 内存,运行的是内核版本为 3.10 的 Red Hat,我想为连续的 DMA 提供 4GB 内存。我知道首选方法是分散/聚集,但在我的情况下这是不可能的,因为有一个硬件芯片将串行协议(protocol)转换为我无法控制的 DMA,我唯一可以控制的是向输入地址(即,从外部系统看到的地址零可以映射到本地总线上的地址 0x700000000)。
由于这是一台一次性实验室机器,我认为最快/最简单的方法是使用 mem=28GB 启动配置参数。我有这个工作正常,但从虚拟空间访问该内存的下一步是我遇到问题的地方。这是我的代码浓缩到相关组件:
在内核模块中:
size_t len = 0x100000000ULL; // 4GB
size_t phys = 0x700000000ULL; // 28GB
size_t virt = ioremap_nocache( phys, len ); // address not usable via direct reference
size_t bus = (size_t)virt_to_bus( (void*)virt ); // this should be the same as phys for x86-64, shouldn't it?
// OLD WAY
/*size_t len = 0x400000; // 4MB
size_t bus;
size_t virt = dma_alloc_coherent( devHandle, len, &bus, GFP_ATOMIC );
size_t phys = (size_t)virt_to_phys( (void*)virt );*/
在应用程序中:
// Attempt to make a usable virtual pointer
u32 pSize = sysconf(_SC_PAGESIZE);
void* mapAddr = mmap(0, len+(phys%pSize), PROT_READ|PROT_WRITE, MAP_SHARED, devHandle, phys-(phys%pSize));
virt = (size_t)mapAddr + (phys%pSize);
// do DMA to 0x700000000 bus address
printf("Value %x\n", *((u32*)virt)); // this is returning zero
另一件有趣的事情是,在执行所有这些操作之前,从 dma_alloc_coherent 返回的物理地址大于系统上的 RAM 数量 (0x83d000000)。我认为在 x86 中,RAM 将始终是最低地址,因此我希望地址小于 32GB。
如有任何帮助,我们将不胜感激。
最佳答案
不要通过mem
限制系统内存量,而是尝试使用CMA:https://lwn.net/Articles/486301/
使用 CMA 内核命令行参数允许您为保证连续的 DMA 操作保留一定数量的内存。内核将允许非 DMA 进程访问该内存,但一旦 DMA 操作需要该内存,非 DMA 进程将被逐出。因此,我建议不要更改您的 mem
参数,而是将 cma=4G
添加到您的 cmdline。 dma_alloc_coherent
应该会自动从该保留空间中提取数据,但您可以在内核配置中启用 CMA 调试以确保这一点。
关于c++ - 大型 PCIe DMA Linux x86-64,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33817481/
在 PCIe 配置中,设备具有专用地址,并且它们以点对点模式相互发送数据 - 每个设备都可以随时写入,并且交换机会注意正确地转发数据。不需要“总线主控器”来决定何时以及如何传输数据。 DMA 如何在这
我正在尝试使用 Linux DMA 驱动程序。目前,当我发送交易并开始等待时,我的请求超时。我相信这与我在执行 DMA 映射时设置缓冲区的方式有关。 char *src_dma_buffer = km
如上所述,dma 引擎和 dma Controller (重点是 linux)有什么区别? linux dma 引擎什么时候到位?这是一个特殊的设备还是所有支持 dma 的外围设备的一部分? 在浏览l
DMA 缓冲区是由驱动程序映射的内存。例如,在使用 rtl8319 的 pci-skeleton.c 中,我们有: tp->tx_bufs = pci_alloc_consistent(tp->p
什么是 Linux 内核上下文中的 DMA 映射和 DMA 引擎?什么时候可以在 Linux 设备驱动程序中使用 DMA 映射 API 和 DMA 引擎 API?任何真正的 Linux 设备驱动程序示
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 5 年前。
我正在更新一个旧的 linux 驱动程序,该驱动程序通过 DMA 将数据传输到用户空间页面,这些页面通过 get_user_pages() 从应用程序向下传递。 我的硬件是一个新的基于 x86 Xeo
我想将 8 位并行数据从 IO 传输到内存,数据以大约 5 Mhz 的速度非常快地传输,我正在通过使用 S3C2440(400Mhz)处理器的友好 arm 在基于 ARM9 的套件上使用嵌入式 lin
我正在尝试在基于 Zynq-7000 的平台上使用 DMA 引擎将 PCM 流传输到 Zynq PL 中的自定义 I2S Controller 。我的 I2S Controller 连接到外部放大器。
假设 CPU 修改了位置 x+50 的值并且没有将其刷新回主存(回写)。 与此同时,设备发起从 x 到 x+100 的 DMA 读取请求。 在那种情况下,如何通知 CPU 刷新脏缓存行? 最佳答案 D
假设CPU要从PCI Express设备进行DMA读取传输。与PCI Express设备的通信由事务层数据包(TLP)提供。从理论上讲,TLP的最大有效负载大小为1024个双字。那么,当CPU向PCI
这是引用this对类似 dma/pci 问题的回答。我从这个答案中得知,PC 没有能够将数据传输到 PCI 卡或从 PCI 卡传输数据的 DMA,并且 PCI 卡必须提供 DMA 功能。我从同事那里收
我一直在使用 Teensy 3.6 微 Controller 板(180 MHz ARM Cortex-M4 处理器)来尝试实现传感器驱动程序。传感器通过 SPI 进行控制,当命令它进行测量时,它会通
我给你讲个故事: 我有两个缓冲区设置,用于执行所谓的 ping ponging。我有一个指向每个缓冲区的 DMA 系统。 系统设置为 DMA 将数据写入一个缓冲区,而中断处理另一个缓冲区中的数据。 看
在 AMD APP 编程指南中写道(第 4-15 页): 对于传输 <=32 kB:对于从主机到设备的传输,数据由 CPU 复制 到运行时固定的主机内存缓冲区,然后 DMA 引擎传输 数据到设备内存。
我目前正在使用 STM32f407G-DISC1,并尝试使用 ADC 和 DMA 回调捕获缓冲区。 频率发生器连接到引脚 A0,并且电路板接地。我用示波器确认我的电线没有损坏。 现在的问题是,在设置我
memcpy via user space DMA: 是否有可能在 linux 中通过用户空间 DMA 实现 memcpy?我知道有一些方法可以通过 DMA 将内核缓冲区复制到用户空间缓冲区,但想通过
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
我正在遵循这个框架 https://forums.xilinx.com/xlnx/attachments/xlnx/ELINUX/10693/1/Linux%20DMA%20from%20User%2
最近,我阅读了很多关于 10gb/s NIC 的网站和书籍,它们的 DMA 以及 linux 内核(10/100 mb/s NIC)处理数据的方式,我遇到了一些问题头脑。 将 10GB/s 的数据流从
我是一名优秀的程序员,十分优秀!