http://blog.csdn.net/remme123/article/details/14139929
Linux/arm 3.4.67 Kernel Configuration中多了一项:
Patch physical to virtual translations at runtime
帮助信息解释如下:
CONFIG_ARM_PATCH_PHYS_VIRT:
│
│ Patch phys-to-virt and virt-to-phys translation functions at
│ boot and module load time according to the position of the
│ kernel in system memory.
│
│ This can only be used with non-XIP MMU kernels where the base
│ of physical memory is at a 16MB boundary.
│
│ Only disable this option if you know that you do not require
│ this feature (eg, building a kernel for a single machine) and
│ you need to shrink the kernel to the minimal size.
意思就是对物理-虚拟地址互相转换进行修改,该功能会根据内核在系统中的位置自动计算出相应地址。
体现在代码上的改动可以在
arch/arm/include/asm/memory.h:
- #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
另外,再额外提供一段有用的信息,也是在这个文件里面:
- #ifndef PHYS_OFFSET
- #ifdef PLAT_PHYS_OFFSET
- #define PHYS_OFFSET PLAT_PHYS_OFFSET
- #else
- #define PHYS_OFFSET UL(CONFIG_PHYS_OFFSET)
- #endif
- #endif
- /*
- * PFNs are used to describe any physical page; this means
- * PFN 0 == physical address 0.
- *
- * This is the PFN of the first RAM page in the kernel
- * direct-mapped view. We assume this is the first page
- * of RAM in the mem_map as well.
- */
- #define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT)
- /*
- * 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 phys_addr_t virt_to_phys(const volatile void *x)
- {
- return __virt_to_phys((unsigned long)(x));
- }
- static inline void *phys_to_virt(phys_addr_t x)
- {
- return (void *)(__phys_to_virt((unsigned long)(x)));
- }