什么是PFN?

作者 by adtxl / 2022-04-15 / 暂无评论 / 396 个足迹

1. pfn的基础概念

linux系统使用分页机制,将物理内存分成每个大小为4K的页。PFN,即page frame number的缩写,取值范围是0--(memory size >> 12)

但是由于物理内存映射的关系,物理内存的0地址对应到系统上并不是物理地址的0.
例如,s3c2440上,内存的地址是从0x30000000开始的。当连接ram后,ram的0地址在s3c2440看来,就是0x30000000。所以在系统中pfn的值应该等于(physical address - memory base address)>> 12

在linux中,cpu看到的都是虚拟地址。所以虚拟地址转换为pfn,需要先将虚拟地址转换为物理地址,内核提供了下面两个宏,可以将内核线性空间的虚拟地址和pfn转换:

#define virt_to_pfn(kaddr)  (__pa(kaddr) >> PAGE_SHIFT)   //__pa() 将虚拟地址转化成物理地址
#define pfn_to_virt(pfn)    __va((pfn) << PAGE_SHIFT)

所以pfn在linux内核中应该对应的是页帧号。可以通过简单的转换找到对应的物理地址。

每个物理上的页,内核给与之分配了一个描述符来描述: page。 pfn可以和page进行转换:

#define page_to_pfn __page_to_pfn
#define pfn_to_page __pfn_to_page

虚拟地址也可以和page进行转换:

#define virt_to_page(addr)  (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
#define page_to_virt(page)  ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)

所有的page结构存放在mem_map中,方便进行管理。

参考

1.linux的内存管理概述

独特见解