woailaoxiang 发表于 2013-07-12 09:37

MMU虚拟内存map的问题

在驱动编程时,可以用ioremap实现物理内存到虚拟内存的转换,

如果我用kmalloc申请了一段内存,返回内存指针,
通过什么方法可以把这个返回的内存指针转换到其对应的物理地址?

因为我想DMA进行数据传输,而DMA只认物理内存。

谢谢!!

wwxxxxll 发表于 2013-07-12 14:29

#include <asm/memory.h>//linux-3.2.36
#ifndef __virt_to_phys
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT

/*
* Constants used to force the right instruction encodings and shifts
* so that all we need to do is modify the 8-bit constant field.
*/
#define __PV_BITS_31_24 0x81000000

extern unsigned long __pv_phys_offset;
#define PHYS_OFFSET __pv_phys_offset

#define __pv_stub(from,to,instr,type)                   \
      __asm__("@ __pv_stub\n"                         \
      "1:   " instr "       %0, %1, %2\n"         \
      "       .pushsection .pv_table,\"a\"\n"         \
      "       .long   1b\n"                           \
      "       .popsection\n"                        \
      : "=r" (to)                                     \
      : "r" (from), "I" (type))

static inline unsigned long __virt_to_phys(unsigned long x)
{
      unsigned long t;
      __pv_stub(x, t, "add", __PV_BITS_31_24);
      return t;
}

static inline unsigned long __phys_to_virt(unsigned long x)
{
      unsigned long t;
      __pv_stub(x, t, "sub", __PV_BITS_31_24);
      return t;
}
#else
#define __virt_to_phys(x)       ((x) - PAGE_OFFSET + PHYS_OFFSET)
#define __phys_to_virt(x)       ((x) - PHYS_OFFSET + PAGE_OFFSET)
#endif
#endif

你不用关这一大堆,用__virt_to_phys(x)就可以了。

lelee007 发表于 2013-07-21 23:31

LS正解

对于kmalloc申请的,X86上直接减去PAGE_OFFSET即是物理地址,一些嵌入设备上还需要加上PHYS_OFFSET
页: [1]
查看完整版本: MMU虚拟内存map的问题