有关DMA的问题

向XTANG请教以下两个问题:
1)DMA缓存是否一定要用mmap()来分配,并且用mem_offset()来得到物理地址?如果直接对一块多进程的共享内存能不能通过调用mem_offset得到各个连续块的物理地址,从而直接用于scatter-gather DMA,或者分配的连续物理内存能不能多进程共享?这样的话就可以模拟WINDOWS上对用户地址进行直接IO了。
2)mmap()用于分配连续物理内存时,不指定PROT_NOCACHE行不行,因为我打算在需要进行DMA的时候自己调用CACHE_FLUSH和CACHE_INVALIDATE。

理论上应该可以“直接对一块多进程的共享内存能不能通过调用mem_offset得到各个连续块的物理地址,从而直接用于scatter-gather DMA” ,当然你的DMA控制器要支持scatter-gather DMA.

但这样相对麻烦,为什么不用mmap()分配一大块 "物理连续内存”并且“多进程共享”呢?只是mmap()时加个标志位就行了,不是吗?

可以,这个是推荐做法。_NOTCACHE现在通常只在mmap()寄存器时用了。数据空间可以自己flsuh/inval.

连续物理内存怎么共享呢?我通过mmap()得到的是虚拟地址,其它的进程怎么得到这块地址呢?(可以像共享内存一样可以命名?还是本来就是共享内存,而只是指定申请连续物理内存的标志?)

如果我在x86平台上,是否可以不用flush/inval?似乎x86本身具有硬件snoop功能,能够自动维护缓存一致性。再者,如果为了考虑移植性用了以上两个函数,会对x86平台上的性能造成影响吗?

谢谢!

最简单的办法是找出物理地址,把长度、物理地址传给另一进程,另一进程map就行了。(MAP_SHARED)

否则用shm_open()创立一个共享内存,然后mmap()它。

理论上可以不用。但即使用了也不要紧。如果是x86,则flash/inval就变成non-op了。看一眼头文件就明白了。

shm_open()创建的共享内存得到一个fd,如果把这个fd用于mmap()是不能用于分配连续物理内存的吧,文档上说要用NOFD。

oops, 是我想当然了。你说的对,不能这样用…