iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0
自我挑戰組

Linux Kernel 網路巡禮系列 第 17

記憶體管理 (2) - Paging 機制

  • 分享至 

  • xImage
  •  

在分頁機制下,Linear Address Space(線性地址空間)和 Physical Address Space(物理地址空間)都會被切割成以頁(Page)為單位的區塊,通常來說,每個頁的大小是 4 KB。Paging 機制的作用就是在建立線性地址空間和物理地址空間之間的頁映射關係。

https://ithelp.ithome.com.tw/upload/images/20241001/20152703boeoTvN9yB.png

一個記憶體地址在Paging 機制下,可以看成頁索引跟位移量的組合,當 MMU 接收到一個地址查詢請求時,會先將Linear Address Space 的頁索引換成 Physical Address Space的頁索引,在加回 Offset 就能夠拿到對應的物理地址。

Page Table(頁表)

在 CPU 內部,維護 Linear Address Space Page 和 Physical Address Space Page 對應關係的表格稱為 Page Table(頁表)。最簡單的實現方式是使用線性地址的一部份作為頁表索引 (非正式: Linear Page Index),然後每個頁表項目(Page Table Entry, PTE)保存對應的 Physical Page Index (非正式)。

https://ithelp.ithome.com.tw/upload/images/20241001/20152703LlTOlarB9U.png

然而,這樣的實現方式會產生很大的成本。例如,在 32 位元的地址架構下,最大地址空間為 4 GB,這意味著可以劃分出 4 * 1024 * 1024 / 4 = 1048576 個 4 KB 大小的頁。由於大多數程式並不會使用全部 4 GB 的地址空間,因此大多數 PTE 都不會連結到物理頁,造成極大的浪費。

為了解決這個問題,實務上會採用多層級的 Page Table。在 Intel 的架構下,最多會使用到五層頁表,不過這邊我們以四層為例。

https://ithelp.ithome.com.tw/upload/images/20241001/20152703IyQdT9GjAh.png

當 MMU 在查找 Linear Address 與 Physical Address 的對應關係時,會依序通過每一層頁表來找到最終的 PTE。這些頁表層級從上到下分別是:Page Map Level 4 (PML4) Table、Page Directory Pointer Table、Page Directory 以及 Page Table。每一層頁表都使用 Linear Address 裡面的一段作為 entry index(索引),每個 entry 保存下一層頁表的起始地址。

這種多層結構的好處在於,如果一段連續的地址空間沒有對應的物理記憶體,作業系統無需保存該區域的下層頁表,只需在上層頁表標註為無效即可。

例如,若一個程式使用 10 MB 的空間,會使用到 10 * 1024 / 4 = 2560 個 PTE。由於每張頁表可以包含 512 個 entry,因此需要 5 張 Page Table 和 1 張 Page Directory Table (PDT) 來索引這些頁表。因此整個系統只需 1 張 PML4T、1 張 PDPT、1 張 PDT 以及 5 張 Page Table,共計 (1+1+1+5) * 512 = 4096 個條目,相較於單層頁表的 1048576 個條目,這節省了大量的空間。

每個 Process 都有各自獨立的虛擬地址空間,因此也會有各自的 Page Table。當 CPU 執行不同的 Process 時,會通過 page-directory base register (PDBR) 來記錄當前 Process 的 PML4 Table 地址,在 Intel 架構中稱為 CR3 暫存器。

TLB(Translation Lookaside Buffer)

儘管多層頁表能夠有效管理記憶體空間,但它也帶來了存取效率的問題。每次存取記憶體時,MMU 要存取4次記憶體,經過多層索引才能找到目標物理地址,這會造成顯著的延遲。為了解決這個問題,MMU 引入了 TLB(Translation Lookaside Buffer),它是一張暫存表,記錄部分 Linear Address Page 和 Physical Address Page 的對應關係。當 MMU 收到查詢請求時,會先查詢 TLB,若查無結果,才會進行多層頁表的索引

Page Fault & Allocation

在 Linux Kernel 中,page 結構負責維護每一個物理頁的使用情況。

// linux/mm_types.h
struct page {
    ...
    atomic_t _refcount;
    ...
}

Linux 在初始化時,為實體記憶體中的每個 Page 建立一個對應的 page 結構,並記錄其使用狀況。當程式試圖存取沒有映射到物理頁的線性地址空間時,MMU 會觸發一個 Page Fault Exception,進入 Kernel Mode 分配新的物理記憶體。Kernel 會找到一個閒置的 page(_refcount 為 0),並更新頁表來建立映射。

分頁機制的功能

透過分頁機制,CPU 將線性地址空間與物理地址空間完全切割開來,這帶來了幾個重要的特性:

  1. 無限大的線性地址空間:因為線性地址空間可以包含沒有實際對應到物理記憶體的頁,所以線性地址空間的大小不受實體記憶體限制。
  2. 簡化記憶體分配:分頁機制使 Process 間的記憶體分配問題轉化為頁分配問題,每個頁都有固定大小,因此分配更加簡單。同時,Process 看到的連續記憶體可以由不連續的物理頁組成,避免了物理記憶體中的連續空間不足問題。
  3. 記憶體隔離:每個 Process 都有獨立的頁表,OS 可以通過控制頁表來實現不同 Process 之間的記憶體隔離。

總結

Paging 機制是記憶體管理的核心技術。程式能夠有效且安全地使用記憶體,同時操作系統也能夠保證不同程式之間的記憶體隔離與管理。


上一篇
記憶體管理 (1) - Address Space
下一篇
記憶體管理 (3) - Segmentation 機制
系列文
Linux Kernel 網路巡禮30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言