C 为DMA使用保留内存

C 为DMA使用保留内存,c,linux,linux-kernel,driver,dma,C,Linux,Linux Kernel,Driver,Dma,我试图利用在引导时向Linux传递“mem”参数时保留的连续内存 现在,我有了我先前保留的这个空间的物理地址,以及它的长度,我希望在我的驱动程序中将这个保留空间用于DMA目的 通常我会使用dma\u alloc\u coherent(),如果我使用的是CMA,我也会使用它,但在这种情况下,它是不同的 现在,我已经了解到,将物理空间映射到内核虚拟空间的一种可接受的方法是使用ioremap 并且,为DMA目的“接管”连续空间的一种可接受的方法是使用DMA\u map\u single(将其映射为总线

我试图利用在引导时向Linux传递“mem”参数时保留的连续内存

现在,我有了我先前保留的这个空间的物理地址,以及它的长度,我希望在我的驱动程序中将这个保留空间用于DMA目的

通常我会使用
dma\u alloc\u coherent()
,如果我使用的是CMA,我也会使用它,但在这种情况下,它是不同的

现在,我已经了解到,将物理空间映射到内核虚拟空间的一种可接受的方法是使用
ioremap

并且,为DMA目的“接管”连续空间的一种可接受的方法是使用
DMA\u map\u single
(将其映射为总线地址)

我很难把两者结合起来
ioremap
工作并返回一个虚拟地址。现在,我已经读到,这不是普通的虚拟地址,我应该只使用访问方法来读/写这个内存

问题是,当我尝试将此虚拟地址传递到
dma\u map\u single
时,它不会报告错误,但我怀疑这是错误的

我做得对吗?我该怎么做才能让它正常工作

10倍

你做得对
您不需要分配内存,因为您已经在启动时设置了内存,但您需要使用dam_map_single来防止缓存问题,例如,如果您想从内存到设备进行DMA,但RAM与二级缓存不同步(缓存有较新版本)你会得到错误的数据,所以你需要在DMA操作前后映射和取消映射

我懒得搜索,但在这个网站上,这个问题每年发生一次。谢谢。也许我不擅长搜索,但我确实搜索了,发现了不同的变体,但与我的案例完全不同。谢谢。我不确定传递dma\u map\u single ioremap地址是否正确。@Liran很抱歉破解该线程,但使用ioremap创建的内存映射未被缓存。因此它可以直接传递给dma设备吗?如果从一个io内存复制到另一个io内存,也可以,但大多数情况下都是从DDR复制到设备(或相反)如果我们在引导时保留DDR,并且DDR内存映射到内核虚拟地址空间,则DDR可以被缓存。根据我的理解,这个内存是非缓存的。如果底层平台不支持IOMMU,我认为我们可以将物理地址传递给设备并请求进行DMA。我的理解错了吗?你是对的,但是你仍然需要“告诉”CPU你正在做一个DMA请求,这样在它结束之前它不会接触到总线参见这里的一个例子