基于msm-5.4
1. 页与页帧号转换
//include/asm-generic/memory_model.h #define pfn_to_page(pfn) (vmemmap + (pfn)) #define page_to_pfn(page) (unsigned long)((page) - vmemmap)
注:使能了 CONFIG_SPARSEMEM_VMEMMAP 才使用的是这一组宏。vmemmap是一个struct page*类型的指针,实际上是当做数组使用。sizeof(page)=64,指针相减为偏移元素个数。
2. 页与物理地址转换
//include/linux/pfn.h #define PFN_PHYS(x) ((phys_addr_t)(x) << PAGE_SHIFT) //x<<12 #define PHYS_PFN(x) ((unsigned long)((x) >> PAGE_SHIFT)) //include/asm-generic/memory_model.h #define __phys_to_pfn(paddr) PHYS_PFN(paddr) #define __pfn_to_phys(pfn) PFN_PHYS(pfn) //arm64/include/asm/memory.h #define page_to_phys(page) (__pfn_to_phys(page_to_pfn(page))) #define phys_to_page(phys) (pfn_to_page(__phys_to_pfn(phys))) //page_to_phys 展开后:(page - vmemmap) << PAGE_SHIFT) //phys_to_page 展开后:vmemmap + (phys >> PAGE_SHIFT)
注:指针相减去,是struct page元素偏移个数,而不是单纯的数值相减。
3. 页与虚拟地址转换
//arm64/include/asm/memory.h #define page_to_virt(x) ({ \ __typeof__(x) __page = x; \ u64 __idx = ((u64)__page - VMEMMAP_START) / sizeof(struct page);\ u64 __addr = PAGE_OFFSET + (__idx * PAGE_SIZE); \ (void *)__tag_set((const void *)__addr, page_kasan_tag(__page));\ }) #define virt_to_page(x) ({ \ u64 __idx = (__tag_reset((u64)x) - PAGE_OFFSET) / PAGE_SIZE; \ u64 __addr = VMEMMAP_START + (__idx * sizeof(struct page)); \ (struct page *)__addr; \ }) //展开后为: #define page_to_virt(x) \ (void *)(((u64)x - VMEMMAP_START)/sizeof(struct page) * PAGE_SIZE + PAGE_OFFSET) #define virt_to_page(x) \ (struct page *)(VMEMMAP_START + ((((u64)x - PAGE_OFFSET) / PAGE_SIZE) * sizeof(struct page)))
4. page_address
实现是在 mm/highmem.c 中,返回page页映射的虚拟地址。实验,从伙伴系统中分配出页,其返回的虚拟地址与 page_to_virt(x) 返回的虚拟地址相等。
注:头文件包含关系
#include <linux/mm.h> #include <linux/mmdebug.h> #include <linux/gfp.h> #include <linux/bug.h> #include <linux/list.h> #include <linux/mmzone.h> #include <linux/rbtree.h> #include <linux/atomic.h> #include <linux/debug_locks.h> #include <linux/mm_types.h> #include <linux/mmap_lock.h> #include <linux/range.h> #include <linux/pfn.h> #include <linux/percpu-refcount.h> #include <linux/bit_spinlock.h> #include <linux/shrinker.h> #include <linux/resource.h> #include <linux/page_ext.h> #include <linux/err.h> #include <linux/page_ref.h> #include <linux/memremap.h> #include <linux/overflow.h> #include <linux/sizes.h> #include <linux/android_kabi.h> #include <linux/android_vendor.h> #include <asm/page.h> #include <linux/personality.h> #include <asm/pgtable-types.h> #include <asm/memory.h> #include <asm-generic/getorder.h> #include <asm/pgtable.h> #include <asm/processor.h> #include <linux/page-flags.h> #include <linux/huge_mm.h>
标签:__,常用,phys,函数,pfn,内存,include,page,define From: https://www.cnblogs.com/hellokitty2/p/18278281