Linux內核內存管理:地址轉換和MMU


地址轉換和MMU

虛擬內存是一個概念,是給進程的一種錯覺,因此它認為自己擁有巨大的、幾乎無限的內存,有時甚至比系統實際擁有的內存還要多。每次訪問內存位置時,由CPU將虛擬地址轉換為物理地址。這種機制稱為地址轉換,由
內存管理單元(MMU)完成,是CPU的一部分。

MMU保護內存免受未經授權的訪問。給定一個進程,需要訪問的任何頁面必須存在於進程VMAs中,因此必須存在於進程頁表中(每個進程都有自己的頁表)。

內存由固定大小的命名頁(用於虛擬內存)和幀(用於物理內存)組織,在我們的示例中大小為4 KB。無論如何,您不需要猜測您為之編寫驅動程序的系統的頁面大小。它是通過內核中的PAGE_SIZE宏定義和訪問的。因此,請記住,頁面大小是由硬件(CPU)決定的。
考慮到一個4 KB的頁面大小的系統,0到4095字節屬於第0頁,4096-8191字節屬於第1頁,以此類推。

引入頁表的概念來管理頁和框架之間的映射。頁面分布在各個表上,這樣每個PTE都對應於頁面和框架之間的映射。然后給每個進程一組頁表來描述它的整個內存空間。

為了遍歷頁面,每個頁面都分配了一個索引(類似數組),稱為頁號。當談到一個框架,它是PFN。這樣,虛擬內存地址由兩部分組成:頁號和偏移量。偏移量表示地址的低12位有效位,而在8kb頁面大小的系統中,低13位有效位表示地址:

操作系統或CPU如何知道哪個物理地址對應一個給定的虛擬地址?他們使用頁表作為轉換表,並且知道每個條目的索引是一個虛擬頁碼,值是PFN。要訪問給定虛擬內存的物理內存,操作系統首先提取偏移量、虛擬頁號,然后遍歷進程的頁表,以便匹配虛擬頁號和物理頁。
一旦匹配發生,就可以訪問該頁面幀中的數據:

 

偏移量用來指向幀中的正確位置。頁表不僅包含物理頁號和虛擬頁號之間的映射,還包含訪問控制信息(讀寫訪問、特權等):

                  Virtual to physical address translation

 

用來表示偏移量的位數由內核宏PAGE_SHIFT定義。PAGE_SHIFT是左移一位以獲得PAGE_SIZE值的位數。它也是右移將虛擬地址轉換為頁碼和物理地址轉換為PFN的位數。下面是這些宏的定義/include/asm-generic/page.h:

#define PAGE_SHIFT 12
#ifdef __ASSEMBLY__
#define PAGE_SIZE (1 << PAGE_SHIFT)
#else
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#endif

頁表是部分解決方案。讓我們看看這是為什么。大多數架構需要32位(4字節)來表示一個PTE,每個進程都有其私有的3gb用戶空間地址,所以我們需要786432個條目來描述和覆蓋一個進程地址空間。它表示每個進程花費了太多的物理內存,只是為了描述內存映射。事實上,一個進程通常使用它的虛擬地址空間的一小部分但分散的部分。為了解決這個問題,我們引入了關卡的概念。頁表按級別(頁級)分層。存儲多級存儲器所必需的空間。

為了解決這個問題,我們引入了分級的概念。頁表按級別(頁級)分層。存儲多級頁表所需的空間只取決於實際使用的虛擬地址空間,而不是與虛擬地址空間的最大大小成比例。這樣,就不再表示未使用的內存,並且頁表遍歷時間也減少了。這樣,第N層的每個表項都指向第N+1層的表項。第1級是較高的級別。

Linux使用一個四級分頁模型:

  • Page Global Directory (PGD):它是第一級(第一級)頁表。在內核中,每個條目的類型都是pgd_t(通常是unsigned long),並指向表中的第二級條目。在內核中,tastk_struct結構表示一個進程的描述,該描述又有一個類型為mm_struct的成員(mm),它描述並表示進程的內存空間。在mm_struct中,有一個特定於處理器的字段pgd,它是一個指針,指向進程的level-1 (pgd)頁表的第一個條目(條目0)。每個進程有且只有一個PGD,它可能包含多達1024個條目。
  • Page Upper Directory (PUD):這只存在於使用四級表的體系結構上。它代表了間接的第二層。
  • 頁面中間目錄(PMD):這是第三個間接級別,僅存在於使用四級表的體系結構上。
  • 頁表(PTE):樹的葉子。它是一個pte_t數組,其中每個入口都指向物理頁面。

並不是所有的級別都被使用。i.MX6的MMU只支持兩層頁表(PGD和PTE),這是幾乎所有32位的情況。在這種情況下,PUD和PMD被簡單地忽略。

                    Two-level tables overview

您可能會問MMU是如何知道進程頁表的。它很簡單,MMU不存儲任何地址。相反,在CPU中有一個特殊的寄存器,稱為頁表基址寄存器(PTBR)或轉換表基址寄存器0 (TTBR0),它指向進程的level-1(頂級)頁表(PGD)的條目0。它正是mm_struct的pdg字段指向:current->mm.pgd = = TTBR0。

在上下文切換(當一個新的進程被調度並且給定了CPU)時,內核立即配置MMU並使用新進程的pgd更新PTBR。現在,當一個虛擬地址給MMU,它使用PTBR的內容來定位進程的第1級頁表(PGD),然后它使用第1級索引,從虛擬地址的最有效位(MSBs)中提取,查找適當的表項,該表項包含指向適當的第2級頁表基址的指針。然后,從該基地址開始,它使用level-2索引查找適當的條目,以此類推,直到它到達PTE。ARM架構(在我們的例子中是i.MX6)有一個兩層的頁表。在本例中,第2級條目是PTE,並指向物理頁面(PFN)。這一步只找到物理頁面。為了訪問頁面中確切的內存位置,MMU提取內存偏移量,也就是虛擬地址的一部分,並指向物理頁面中相同的偏移量。

當一個進程需要讀取或寫入內存位置(當然,我們討論的是虛擬內存)時,MMU將執行轉換到該進程的頁表中,以找到正確的條目(PTE)。虛擬頁碼是從虛擬地址中提取出來的,處理器將其用作進程頁表的索引,以檢索其頁表條目。如果在該偏移量處有一個有效的頁表條目,處理器將獲取PFN從這個條目。如果沒有,則意味着進程訪問了其虛擬內存的未映射區域。然后引發一個頁面錯誤,操作系統應該處理它。

在現實世界中,地址轉換需要頁表遍歷,而且並不總是一次性操作。內存訪問實例的數量至少與表級別相同。一個四級頁表需要4次內存訪問。換句話說,每個虛擬訪問實例將導致5次物理內存訪問。如果虛擬內存的訪問比物理訪問慢四倍,那么虛擬內存的概念就毫無用處了。

幸運的是,SoC制造商努力尋找一個聰明的技巧來解決這個性能問題: 現代cpu使用一個稱為轉義查找緩存(TLB)的小型且非常快的關聯內存,來緩存最近訪問的虛擬頁面的pte。

頁面查找和TLB

 在MMU繼續處理轉換之前,還涉及到另一個步驟。正如有一個緩存用於最近訪問的數據,也有一個緩存用於最近翻譯的地址。由於數據緩存可以加快數據訪問過程,TLB可以加快虛擬地址轉換的速度。是的,地址轉換是一項棘手的任務。它是內容尋址內存(CAM),其中鍵是虛擬地址,值是物理地址。換句話說,TLB是MMU的緩存。在每次內存訪問時,MMU首先檢查TLB中最近使用的頁面,TLB包含一些當前分配給物理頁面的虛擬地址范圍。

 TLB是如何工作的?

在虛擬內存訪問中,CPU遍歷TLB,試圖找到正在被訪問的頁面的虛擬頁號。這個步驟稱為TLB查找。當找到一個TLB表項時(匹配發生),就說有一個TLB命中,CPU繼續運行,並使用在TLB表項中找到的PFN來計算目標物理地址。TLB命中時不會出現頁面錯誤。正如您所看到的,只要在TLB中可以找到一個轉換,虛擬內存訪問將和物理訪問一樣快。如果沒有找到TLB表項(沒有匹配),你說有一個TLB缺失。

在TLB miss事件中,有兩種可能,這取決於處理器類型;TLB miss事件可以由軟件來處理,也可以由硬件通過MMU來處理:

  • 軟件處理: CPU引起TLB miss中斷,被操作系統捕獲。然后,操作系統遍歷進程的頁表,找到正確的PTE,如果有匹配的有效的條目,CPU就會把新的翻譯安裝到TLB。否則,將執行頁面錯誤處理程序。
  • 硬件處理: 由CPU(實際上是MMU)在硬件中遍歷進程的頁表。如果有匹配且有效的條目,CPU會在TLB中添加新的翻譯。否則,CPU將引發頁面錯誤中斷,由操作系統處理。

在這兩種情況下,頁面錯誤處理程序是相同的:執行do_page_fault()函數,這是依賴於體系結構的。對於ARM, do_page_fault在arch/arm/mm/fault.c中定義:

                MMU and TLB walkthrough process

 頁表和頁目錄條目依賴於體系結構。表的結構是否與MMU識別的結構相對應,由操作系統決定。在ARM處理器上,在ARM處理器上,你必須在CP15(協處理器15)寄存器c2中寫入轉換表的位置,然后通過寫入CP15的c1寄存器來啟用緩存和MMU。從http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0056d/BABHJIBH.htm 和 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0433c/CIHFDBEJ.html獲取更詳細的信息。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM