在linux中,pfn全名為“page frame number”,是物理記憶體區域編號。 「page frame」是針對實體記憶體而言的,把實體記憶體分成一個個的page size的區域,並且給每一個page編號,而這個編號就是PFN。
本教學操作環境:linux5.9.8系統、Dell G3電腦。
1、什麼是page frame?
作業系統最重要的作用之一就是管理電腦系統中的各種資源,做為最重要的資源:內存,我們必須管理起來。在linux作業系統中,實體記憶體是依照page size來管理的,具體page size是多少是和硬體以及linux系統配置相關的,4k是最經典的設定。因此,對於物理內存,我們將其分成一個個按page size排列的page,每一個物理內存中的page size的內存區域我們稱為page frame。我們針對每一個物理的page frame建立一個struct page的資料結構來追蹤每一個實體頁面的使用情況:是用於內核的正文段?還是用於進程的頁表?是用於各種file cache還是處於free狀態…
每一個page frame有一個一一對應的page資料結構,系統中定義了page_to_pfn和pfn_to_page的巨集用來在page frame number和page資料結構之間進行轉換,具體如何轉換是和memory modle相關,我們會在第三章詳細描述linux kernel中的3種記憶體模型。
2、什麼是PFN?
對於一個電腦系統,其整個實體位址空間應該是從0開始,到實際系統能支援的最大物理空間為止的一段位址空間。在ARM系統中,假設實體位址是32個bit,那麼其實體位址空間就是4G,在ARM64系統中,如果支援的實體位址bit數目是48個,那麼其實體位址空間就是256T。當然,實際上這麼大的實體位址空間並不是都用於內存,有些也屬於I/O空間(當然,有些cpu arch有自己獨立的io address space)。因此,記憶體所佔據的實體位址空間應該是一個有限的區間,不可能涵蓋整個實體位址空間。不過,現在由於記憶體越來越大,對於32位元系統,4G的實體位址空間已經無法滿足記憶體的需求,因此會有high memory這個概念,後續會詳細描述。
PFN是page frame number的縮寫,所謂page frame,就是針對實體記憶體而言的,把實體記憶體分成一個個的page size的區域,並且給每一個page 編號,這個編號就是PFN。假設實體記憶體從0位址開始,那麼PFN等於0的那個頁幀就是0位址(物理位址)開始的那個page。假設實體記憶體從x位址開始,那麼第一個頁幀號碼就是(x>>PAGE_SHIFT)。
PFN的值範圍是 0----(memory size >> 12)。
但是由於物理記憶體映射的關係,物理記憶體的0位址對應到系統上並不是物理位址的0。例如:s3c2440上,記憶體的位址是從0x30000000開始的。當連接ram後,ram的0位址在s3c2440看來,就是0x30000000. 所以在系統中 pfn的值 應該等於 (physical address - memory base address) >> 12 。
但是linux中,用的又都是虛擬位址,所以要先將 virtual address轉換成 physical address 才行。所以在linux中有個巨集定義 將核心線性空間的虛擬位址和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結構存放在mem_map中,方便進行管理。
由於linux是將實體記憶體分成4K大小的頁來進行管理的。所以在軟體上也會設定MMU進行配對對應。後面敘述。
linux將4G的虛擬空間分成了使用者空間和核心空間。使用者空間是0---3G,核心空間是3G---4G。從核心空間可以存取到使用者空間,但是從使用者空間必須透過系統呼叫來能存取核心空間。
相關推薦:《Linux影片教學》
以上是linux中什麼是pfn的詳細內容。更多資訊請關注PHP中文網其他相關文章!