除了分段管理中的LDT和GDT有較大改動,分頁管理中增加了三級分頁模型以外,大部分內容可以參考Linux0.12-記憶體定址
一、分段管理:
1.Linux中,段基址總是0,邏輯地址與線性地址是一致的。
或者說,在Linux中,沒有實際上地使用分段機制
2.一個進程可以使用一個GDT和一個LDT
GDT包含:
(1)LDT在GDT中的描述符
(2)3個局部段描述符
(3)3個與進階電源管理相關的段
(4)5個PnP的BIOS服務程式相關的段
(5)1個特殊的TSS段
(6)1個任務狀態段TSS
(7)核心態和使用者態的程式碼片段和資料區段(共4個)
LDT包含:8191個段
大多數使用者態下的Linux程式不使用KDT,因此核心定義了一個預設的LDT供大多數進程共用。
3.GDT第0項不用,因為防止在加電後段寄存器未經初始化就進入保護模式並使用GDT
二、分頁管理:
1.幾種分頁模型的比較
| |
二級分頁模型 |
三級分頁模型 |
四級分頁模型 |
| 作業系統支援 |
Linux2.6.10以前 |
Linux2.6.10 |
Linux2.6.11 |
| 物理支援 |
32位 |
啟用實體位址延伸(PAE)的32位(物理地址36位,線性地址32位) |
64位 |
| 線性地址格式 |
10位PD + 10位PT + 12位offset |
2位PGD + 9位PMD + 9位PT + 12位offset |
9位PGD + 9位PUD + 9位PMD + 9位PT + 12位offset |
| 頁表項結構 |
20位物理地址 + 12位標誌位 |
24位物理地址 + 12位標誌位 |
|
| 頁面大小 |
4K |
4K |
|
| 頁框數 |
2^20 |
2^24 |
|
| 頁表項大小 |
4B |
8B |
|
| 頁表總大小 |
4MB |
128MB |
|
| 一頁頁表包含的頁表項數 |
1024 |
512 |
|
計算方法:
頁框大小 = 2 ^ offset
頁框數 = 實體記憶體大小 / 頁框大小
頁表項大小 = 頁表長度 / 8
頁表總大小 = 頁框數 * 頁表項大小
一頁頁表包含的頁表項 = 頁面大小 / 頁表項大小
幾級分布就要訪問幾次記憶體
2.為了緩解CPU與RAM之間的速度不匹配,在分頁單元與主記憶體之間,插入一個快取單元cache。
N路組關聯的快取:主存中的任意一個行可以存放在快取N行中的任意一行。
訪問一個RAM儲存單元時,先與快取中的這N行進行匹配
3.為了加快線性地址的轉換,引入了TLB
當CPU的cr3寄存器被修改時,本地TLB自動無效
cr3存放的是PD的基址(這是一個物理地址)、
分段沒有類似的機制,因為段址是二維的。
4.為了使二級頁表模型與三級頁表模型相容,當使用二級頁表時,頁中間目錄僅含有一個指向下屬頁表的目錄項
5.主核心頁全域目錄:
核心維持著一組自己使用的頁表,駐留在主核心頁全域目錄中
主核心頁全域目錄的最高目錄項部分作為參考模型,為系統中的每個普通進程對應的頁全域目錄項提供參考模型
核心頁表的初始化是的實模式下進行的,此時分頁功能還沒有啟用。具體過程參見Linux2.6實體記憶體管理
6.核心線程並不擁有自己的頁表集,它們使用剛在CPU上執行過的普通進程的頁表集
核心線程不訪問使用者態地址空間。
7.記憶體定址過程中出現頁面異常時的處理過程:
圖中的連線沒畫箭頭,都是從左往右指