Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1254175
  • 博文数量: 479
  • 博客积分: 12240
  • 博客等级: 上将
  • 技术积分: 4999
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-24 17:12
文章分类

全部博文(479)

文章存档

2014年(1)

2013年(1)

2012年(1)

2011年(95)

2010年(177)

2009年(167)

2008年(16)

2007年(21)

分类: LINUX

2009-12-05 08:56:03

物理地址到虚拟地址的转换


(1)__phys_to_pfn

定义在arch/arm/include/asm/memory.h文件中:

 125/*
 126 * Convert a physical address to a Page Frame Number and back
 127 */

 128#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT)
 129#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)

这种转换可用在资源分配为的代码中。


另外,__virt_to_phys这一组则仅仅是memory.h的内部函数,不能在memory.h之外使用。如果使用,请用virt_to_phys/phys_to_virt/__pa/__va来替代。

/*
 * Physical vs virtual RAM address space conversion. These are
 * private definitions which should NOT be used outside memory.h
 * files. Use virt_to_phys/phys_to_virt/__pa/__va instead.
 */

#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)


但是,在驱动中也不能使用__pa(x)等

/*
 * Drivers should NOT use these either.
 */

#define __pa(x) __virt_to_phys((unsigned long)(x))
#define __va(x) ((void *)__phys_to_virt((unsigned long)(x)))
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)


也不能使用virt_to_phys等

/*
 * These are *only* valid on the kernel direct mapped RAM memory.
 * Note: Drivers should NOT use these. They are the wrong
 * translation for translating DMA addresses. Use the driver
 * DMA support - see dma-mapping.h.
 */

static inline unsigned long virt_to_phys(void *x)
{
        return __virt_to_phys((unsigned long)(x));
}

static inline void *phys_to_virt(unsigned long x)
{
        return (void *)(__phys_to_virt((unsigned long)(x)));
}


(2)io_p2v

这个好像只在部分处理器上实现了,如PXA的就有arch/arm/mach-pxa/include/mach/hardware.h:

28/*
  29 * Intel PXA2xx internal register mapping:
  30 *
  31 * 0x40000000 - 0x41ffffff <--> 0xf2000000 - 0xf3ffffff
  32 * 0x44000000 - 0x45ffffff <--> 0xf4000000 - 0xf5ffffff
  33 * 0x48000000 - 0x49ffffff <--> 0xf6000000 - 0xf7ffffff
  34 * 0x4c000000 - 0x4dffffff <--> 0xf8000000 - 0xf9ffffff
  35 * 0x50000000 - 0x51ffffff <--> 0xfa000000 - 0xfbffffff
  36 * 0x54000000 - 0x55ffffff <--> 0xfc000000 - 0xfdffffff
  37 * 0x58000000 - 0x59ffffff <--> 0xfe000000 - 0xffffffff
  38 *
  39 * Note that not all PXA2xx chips implement all those addresses, and the
  40 * kernel only maps the minimum needed range of this mapping.
  41 */

  42#define io_p2v(x) (0xf2000000 + ((x) & 0x01ffffff) + (((x) & 0x1c000000) >> 1))
  43#define io_v2p(x) (0x3c000000 + ((x) & 0x01ffffff) + (((x) & 0x0e000000) << 1))


阅读(2091) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~