kmalloc分配的内存可以用来进行dma传输,而在栈中的变量就不能用进行dma传输,这是为什么?
我用的是网卡的dma,只要写进变量的首地址(都已经转换成物理地址)以及长度,它就能够进行传输,但是变量没用kmalloc分配内存,就不能用它的地址进行传输!
是否因为堆和栈转换成物理地址是不连续的?还是其他原因?
12 个解决方案
#1
栈空间在退出函数的时候就回收了,而堆则不会。
#2
不是因为收回的原因 因为我试过在函数里延迟,等待dma完成,结果传出去的数据还是错的
#3
查一下是不是有字节对齐的问题。
#4
回楼上的 也不是字节对齐问题,是不是dma传输都有地址限制的?
#5
关注。
#6
你用的是什么CPU?
#7
at91rm9200
#8
用来做DMA的内存不能Cache, 编译器给变量自动分配的内存会使用cache。 如果CPU没有MMIO的话,申请到的内存一般都是连续的
#9
对于DMA内存,一般需要分配前16M的物理内存,而且要关掉CACHE。Linux的kmalloc可以分配两种内存,DMA内存与非DMA内存,所以为DMA分配的内存都要用GFP_DMA标志。在栈中,分配的内存应该不是DMA内存:1、可能DMA没有从前16M物理内存中分配(你的芯片应该没有这限制)。2、可能没有关掉CACHE(芯片如果支持MMU,一般就支持CACHE)。所以会出现这种问题。
#10
好像,16MB限制只有ISA的设备才有
如果是PCI的可以到4GB
如果是PCI的可以到4GB
#11
无论堆还是栈,使用的都是虚拟内存
但malloc申请到的虚拟内存和物理内存是一对一的映射关系的,即虚拟内存在物理上是连续的
而在栈中分配时,所分配的虚拟内存在逻辑上是连续的,但物理上可能不连续,可能会导致问题
但malloc申请到的虚拟内存和物理内存是一对一的映射关系的,即虚拟内存在物理上是连续的
而在栈中分配时,所分配的虚拟内存在逻辑上是连续的,但物理上可能不连续,可能会导致问题
#12
同意楼上的观点,kmalloc()返回的是一个内核逻辑地址,逻辑地址与实际的物理内存只是有一个简单的偏移,虽说逻辑地址也是虚拟地址,但是它与物理地址是一一对应而且连续的,而堆栈地址在逻辑上是连续的,在物理上并没有一一对应而且线性的关系,所以不能用作DMA传输
#1
栈空间在退出函数的时候就回收了,而堆则不会。
#2
不是因为收回的原因 因为我试过在函数里延迟,等待dma完成,结果传出去的数据还是错的
#3
查一下是不是有字节对齐的问题。
#4
回楼上的 也不是字节对齐问题,是不是dma传输都有地址限制的?
#5
关注。
#6
你用的是什么CPU?
#7
at91rm9200
#8
用来做DMA的内存不能Cache, 编译器给变量自动分配的内存会使用cache。 如果CPU没有MMIO的话,申请到的内存一般都是连续的
#9
对于DMA内存,一般需要分配前16M的物理内存,而且要关掉CACHE。Linux的kmalloc可以分配两种内存,DMA内存与非DMA内存,所以为DMA分配的内存都要用GFP_DMA标志。在栈中,分配的内存应该不是DMA内存:1、可能DMA没有从前16M物理内存中分配(你的芯片应该没有这限制)。2、可能没有关掉CACHE(芯片如果支持MMU,一般就支持CACHE)。所以会出现这种问题。
#10
好像,16MB限制只有ISA的设备才有
如果是PCI的可以到4GB
如果是PCI的可以到4GB
#11
无论堆还是栈,使用的都是虚拟内存
但malloc申请到的虚拟内存和物理内存是一对一的映射关系的,即虚拟内存在物理上是连续的
而在栈中分配时,所分配的虚拟内存在逻辑上是连续的,但物理上可能不连续,可能会导致问题
但malloc申请到的虚拟内存和物理内存是一对一的映射关系的,即虚拟内存在物理上是连续的
而在栈中分配时,所分配的虚拟内存在逻辑上是连续的,但物理上可能不连续,可能会导致问题
#12
同意楼上的观点,kmalloc()返回的是一个内核逻辑地址,逻辑地址与实际的物理内存只是有一个简单的偏移,虽说逻辑地址也是虚拟地址,但是它与物理地址是一一对应而且连续的,而堆栈地址在逻辑上是连续的,在物理上并没有一一对应而且线性的关系,所以不能用作DMA传输