2010年2月24日 星期三

different memory address

kernel logical address: These addresses map most or all of main memory.and are often treated as if they were physical addresses. On most architectures, logical addresses and their associated physical addresses differ only by a constant offset.
内核逻辑地址和物理地址之间只有一个偏移量的差别。而且内核在启动时就是根据这种逻辑地址和物理地址的对应关系给896MB以下内存建立了页表。virt_to_phys只接受这种直接映射的虚拟地址作为参数。

kernel virtual address: ioremap返回的就是这种地址。它在VMALLOC_START和VMALLOC_END之间搜索到一块空闲的虚拟地址空间,把它和物理地址 (ioremap的参数)建立联系,并建立页表。VMALLOC_START是根据最大内存地址的虚拟地址(kernel logical address)计算出来的,如在i386中:
#define VMALLOC_START (((unsigned long) high_memory + 2*VMALLOC_OFFSET-1) & ~(VMALLOC_OFFSET-1))

可见kernel logical address和kernel virtual address 是不一样的,而且在值上是不会重叠的。对kernel virtual address调用virt_to_phys也是没有意义的。
===================================
一种就是在引导时预留RAM,如设置MEM=31M,阻止内核使用最顶部的1M字节,然后用:
dmabuf=ioremap(0x1F00000 /* 31M */, 0x100000 /* 1M */ );

我觉得你这里传给DMA的应该就是0x1F00000, 这就是物理地址,DMA所需要的。ioremap后的到的地址dmabuf是虚拟地址,是给程序用的。DMA操作完后,0x1F00000处就应该有了你要的数据,然后你就可以通过:
memcpy(dest, dmabuf, size)
操作从0x1F00000把数据复制到你想要放的地方。

你这里讲的预留1M的空间实际上已经变成了外设地址空间,因为kmalloc无法分配这块地方。


沒有留言:

張貼留言