Go to My Blog
Go to Lin's Blog

关于Windows下的DMA操作。

这几天遇到了64bit Win8下的一个Bug,我们的chip是支持ScatterGather的,但是在做DMA之前,我们修改对应的Memory却没有生效。

DMA传输出去的内容还是之前没有改过的。

回来的路上,看了下面这篇文章,终于明白其中的原因了。www.microsoft.com/whdc/driver/kernel/dma.mspx

Device跟Memory进行传输DMA的时候,Device能访问的地址访问受Device本身的寻址范围所限。

在我的环境下,Chip是32bit的Bus,所以只能访问0-4G的地址,而系统是64bit的,有些Memory(Mem1)的物理地址在4G以上的空间。

导致Device无法直接拿到,所以OS会额外在0-4G的物理地址开了一块Memory(Mem2),就是所谓的Map Register。

OS把4G以上的Mem1的内容Copy到Mem2,所以DMA拿的其实是Mem2的内容,这就是为什么我修改Mem1,DMA传输的数据却没有变化。

那OS把4G以上的Mem1 copy到4G以下的Mem2是在什么时候做的呢?答案就是NdisMAllocateNetBufferSGList。

所以只要在Call NdisMAllocateNetBufferSGList之前修改数据还是会生效的。

Windows在两种情况下会用到Map Register这种copy memory的机制。

1. Device不支持ScatterGather。

2. 需要DMA的内存的物理地址无法被Device的总线直接访问到。

那篇链接的文档里面关于DMA的操作有很详细的描述。

posted @ 2013-01-30 23:12  一ke小小草  阅读(1535)  评论(0编辑  收藏  举报