- 了解phys_to_virt/virt_to_phys
1.概述
对于提供了MMU的处理器而言,Linux提供了复杂的存储管理系统,使得进程所能访问的内存达到4GB。进程的4GB内存空间被人为的分为两个部分:用户空间与内核空间。用户空间地址分布从0到3GB(PAGE_OFFSET,在0x86中它等于0xC0000000),3GB到4GB为内核空间。
内核空间中,从3G到vmalloc_start这段地址是物理内存映射区域(该区域中包含了内核镜像、物理页框表mem_map等等),比如VMware虚拟系统内存是160M,那么3G~3G+160M这片内存就应该映射物理内存。在物理内存映射区之后,就是vmalloc区域。对于160M的系统而言,vmalloc_start位置应在3G+160M附近(在物理内存映射区与vmalloc_start期间还存在一个8M的gap来防止跃界),vmalloc_end的位置接近4G(最后位置系统会保留一片128k大小的区域用于专用页面映射),kmalloc和get_free_page申请的内存位于物理内存映射区域,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因此存在较简单的转换关系,virt_to_phys()可以实现内核虚拟地址转化为物理地址:
arch/arm/include/asm/memory.h:
131 #ifndef __virt_to_phys
132 #define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
133 #define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
134 #endif
182 static inline unsigned long virt_to_phys(void *x)
183 {
184 return __virt_to_phys((unsigned long)(x));
185 }
186
187 static inline void *phys_to_virt(unsigned long x)
188 {
189 return (void *)(__phys_to_virt((unsigned long)(x)));
190 }
- phys_addr_t virt_to_phys(volatile void * address);
The returned physical address is the physical (CPU) mapping for the memory address given. It is only valid to use this function on addresses directly mapped or allocated via kmalloc.This function does not give bus mappings for DMA transfers. In almost all conceivable cases a device driver should not be using this function
The returned physical address is the physical (CPU) mapping for the memory address given. It is only valid to use this function on addresses directly mapped or allocated via kmalloc.
This function does not give bus mappings for DMA transfers. In almost all conceivable cases a device driver should not be using this function