1 / 72

作業系統

作業系統. 第十章 記憶體管理實作. 記憶體管理實作. 硬體上的支援不可或缺 Linux 使用 Intel 的分頁式分段功能來轉換邏輯位址與實體位址 跨平台:讓 Linux 能在其他非 Intel 平台上執行,記憶體管理模型須不受處理器差異影響 主記憶體分配: 核心:用來儲存核心程式碼與靜態核心資料結構 動態記憶體:其他的部分稱之。可動態給使用者行程或核心使用 動態記憶體的管理影響系統效能甚巨. 第十章 記憶體管理實作. 記憶體定址 硬體分段支援 Linux 上的分段 硬體分頁支援 Linux 上的分頁 頁框管理 記憶體區域管理 摘要.

janae
Download Presentation

作業系統

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 作業系統 第十章 記憶體管理實作

  2. 記憶體管理實作 • 硬體上的支援不可或缺 • Linux 使用 Intel 的分頁式分段功能來轉換邏輯位址與實體位址 • 跨平台:讓 Linux 能在其他非 Intel 平台上執行,記憶體管理模型須不受處理器差異影響 • 主記憶體分配: • 核心:用來儲存核心程式碼與靜態核心資料結構 • 動態記憶體:其他的部分稱之。可動態給使用者行程或核心使用 • 動態記憶體的管理影響系統效能甚巨

  3. 第十章 記憶體管理實作 • 記憶體定址 • 硬體分段支援 • Linux上的分段 • 硬體分頁支援 • Linux上的分頁 • 頁框管理 • 記憶體區域管理 • 摘要

  4. 記憶體定址(1) • Intel 80x86 提供分頁式分段的功能 • 3 種記憶體定址的方式: • 實體位址:記憶體中實際的位址 • 線性位址:一塊 4 GB 大小的虛擬空間;系統利用此空間作分段與分頁 • 透過邏輯位址:可選擇到線性位址空間中一個分段裡的任一個位元組 • 透過分段單元的硬體電路: • 把邏輯位址轉換成線性位址 • 若轉換成功,再透過分頁單元把線性位址轉換成實體位址

  5. 邏輯位址 分段單元 線性位址 分頁單元 實體位址 邏輯位址轉換

  6. 記憶體定址(2) • Intel 架構下,記憶體架構分為 2 部分 • 分段:將程式分割成程式碼、資料與堆疊等模組,使多個工作互不干擾,在同一個處理器上執行 • 分頁:需求分頁,虛擬記憶體 • 分段的做法:將程式的分段劃分在線性位址空間裡 • 分段描述器:記錄此分段起始線性位址及分段的大小 • 可以找到分段的線性位址;避免存取超出此分段以外的空間

  7. 記憶體定址(3) • 邏輯位址由分段選擇器和段偏移組成 • 透過分段選擇器,可從描述器表(如 GDT)中找到此分段的分段描述器得到分段的起始線性位址 • 配合邏輯位址中的段偏移,就能定址到此分段在線性位址空間的位址 • 分頁的做法:將線性位址空間中的分段再細分成許多分頁 • 這些分頁可存放在記憶體或磁碟內 • 作業系統透過分頁目錄和分頁表格,可得分頁在實體記憶體或磁碟中的實際位址

  8. 硬體分段支援(1) • Intel 微處理器以真實模式與保護模式進行位址轉換 • 保護模式下,Intel 架構提供 4G 位元組的實體位址空間(因處理器的位址匯流排為 32 位元) • 真實模式下的硬體分段沒有作用 • 保護模式下的硬體分段支援 • 分段暫存器 • 分段描述器 • 分段選擇器

  9. 硬體分段支援(2) • 分段暫存器: • 儲存分段選擇器的內容,計有 6 個,分別為 cs、ss、ds、es、fs 與 gs • cs 暫存器:指向一個包含程式碼的分段 • ss 暫存器:指向目前的程式堆疊分段 • ds 暫存器:指向靜態或是外部資料分段 • 其他 3 分段暫存器可指向任何分段 • cs 暫存器另一重要功能:包含 2 個CPL位元(定義 CPU 目前權限等級) • 若 CPL 數值為 0,表示最高等級 • 若 CPL 數值為 3,表示最低等級 • 以 Linux 系統為例,利用 CPL 的數值為 0 或 3 來表示目前是處於核心模式或使用者模式

  10. 硬體分段支援(3) • 分段描述器: • 每個分段都用一個 8 位元組的分段描述器來描述該分段的特徵,如分段大小、分段所在位置、存取控制權及狀態等資訊 • 儲存在 GDT(全域描述器表)或 LDT(區域描述器表)中 • 作業系統通常只定義一個 GDT,但每個行程都有各自的 LDT • 主記憶體中,GDT 的位址會存放在 gdtr 暫存器;目前正在使用的 LDT 的位址存在 ldtr 暫存器

  11. 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 BASE (24-31) G D / B 0 A V L LIMIT (16-19) 1 DPL S TYPE BASE (16-23) BASE (0-15) LIMIT (0-15) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 分段描述器格式

  12. 硬體分段支援(4) • 分段描述器中的各項欄位: • G 旗標:設定分段的單位大小 • 當 G 旗標設定為 1 ,分段單位為 4K 位元組;否則分段單位為 1 位元組 • LIMIT欄位:描述分段的長度 • CPU 把分段描述器中第 0 到 15 位元與第 48 到 51 位元合併成 20 個位元的分段界限,且依據 G 旗標的設定形成不同的分段界限範圍 • 如果 G 旗標設定為 0,分段大小會介於 1B(位元組)到 1MB;否則分段大小會介於 4KB 到 4GB • BASE欄位:描述分段的基底位址 • CPU 把分段描述器中的第 16 到 39 位元與第 56 到 63 位元共計 32 位元合併成分段開始的線性位址 • S 旗標: • 若此旗標是 0,表示此分段用來儲存核心資料結構的系統分段;否則代表它是一般的程式碼或資料分段

  13. 硬體分段支援(5) • TYPE欄位:表示分段的型態與存取權限 • DPL(描述器權限)欄位:設定存取該分段的權限 • 範圍由 0 到 3,數值為 0 時表示權限最大 • D/B 旗標:表示分段包含程式碼或資料 • 兩者定義上不同,設定為 1 時表示段偏移的位址為 32 位元,否則只有 16 位元 • P 旗標:設定為 1 時表示該分段在主記憶體中 • 第 53 個位元:是一個保留位元,通常被設定為 0 • AVL欄位:可由作業系統自行定義使用; Linux 沒有使用此欄位

  14. 硬體分段支援(6) • 分段選擇器:加速邏輯位址與線性位址間的轉換 • 額外特殊的暫存器都包含 8 位元組大小的分段描述器 • 當分段選擇器的內容載入到分段暫存器中,該對應的分段描述器也從記憶體載入到對應的特殊暫存器 • 邏輯位址轉換可不透過 GDT 或 LDT;CPU 直接存取非程式控制暫存器的內容 • 只有在分段暫存器的內容改變時才需對 GDT 或 LDT 作讀取

  15. 分段 描述器表 分段描述器 分段暫存器 非程式控制暫存器 分段選擇器 分段描述器 分段選擇器與分段描述器

  16. 硬體分段支援(7) • 分段選擇器的各項欄位: • 分段索引: 13 位元當成描述器表的索引 • TI 旗標:指示分段描述器在 GDT(TI為 0)或在 LDT(TI為 1)中 • RPL(要求者權限)欄位: 2 位元的欄位,指示 CPU 目前的權限等級(要求 CPU 作記憶體存取的使用者權限) • 欲得分段描述器在 GDT 或 LDT 中的相對位址利用分段選擇器中最高 13 個位元的數值乘上 8

  17. 硬體分段支援(8) • 把邏輯位址轉成線性位址的步驟: • 檢查 TI 欄位,確定對應的分段描述器在 GDT 或 LDT 中 • 索引欄位的數值乘以 8 再加上 gdtr 或 ldtr 中的數值分段描述器的位址 • 把邏輯位址的段偏移加上分段描述器中的基底位址欄位,就可以得到線性位址 • 當分段暫存器內容改變時才需要執行前面步驟

  18. gdt 或 ldt 分段描述器 + 線性位址 gdtr 或 ldtr +  8 47 35 34 33 32 31 0 分段索引(35-47) TI RPL 段偏移(0-31) 分段選擇器 邏輯位址 分段選擇器與邏輯位址轉換

  19. Linux 上的分段(1) • Linux 中採用分頁式分段之原因: • 當行程共用相同線性位址,記憶體管理變方便,易達分段共用 • Linux 在設計上想適用於目前各種常用架構可將所有的分段描述器都儲存在 GDT 中 • Linux 中的 GDT 是以 gdt_table 陣列來實作,用變數 gdt 指向該陣列 • 核心中不使用區域描述器表(LDT),但允許行程透過系統呼叫建立 LDT • Linux 下使用多個分段,如核心程式碼分段、核心資料分段、使用者程式碼分段、使用者資料分段、TSS 分段、與 LDT 分段等

  20. Linux 上的分段(2) • TSS 分段: • 存放每個行程暫存器與 I/O 位元映射的內容 • 分段大小的分段界限欄位設定為 0xeb • TYPE 欄位設定為 9 或 11 • 使用者模式下不允許行程存取 TSS 分段,故 DPL 設為 0 • Linux 核心 2.4 中,所有行程的 TSS 分段不存在,改由指向存放原先每個行程 TSS 分段內容的指標來代替

  21. Linux上的分段(3) • LDT 分段: • 儲存在變數 default_ldt 中,預設是給所有的行程所共用 • 每個行程都有自己的分段描述器,指到預設的共用 LDT 分段,分段裡的基底位址欄位設定為 default_ldt 的位址,分段大小的分段界限設定為 7 • 若行程需要一個真正的 LDT,會建立一個長度為 4096 位元組的分段,該分段最多包含 511 個分段描述器,該行程所屬的預設 LDT 分段描述器則被放置到 GDT 中

  22. Linux上的分段(4) • 對每個行程而言,GDT 可以放入 TSS 分段或 LDT 分段 2 種不同的分段描述器 • GDT 中最大可儲存的欄位數目為 12 + 2 × NR_TASKS(NR_TASKS:系統裡行程最大的數目) • 行程被建立時 • TSS 與 LDT 分段描述器被加到 GDT 中 • 核心初始化時 • trap_init( ) 函式利用 set_tss_desc(0 , &init_task.tss) 把第一個行程的 TSS 分段描述器加到 GDT 中 • 第一個行程再利用 copy_thread( ) 建立其他子行程,該函式喚起 clone( ) 與 fork( ) 的系統呼叫,也執行 set_tss_desc(nr , &(task[nr]->tss)) 函式設定新行程的 TSS 分段

  23. Linux上的分段(5) • CPU 的特權等級 • 代表一個行程在使用者模式或是核心模式 • 目前的特權等級可由儲存在 cs 暫存器之分段選擇器內的 RPL 欄位決定 • 當目前的特權等級改變,所對應的分段暫存器也必須修改 • ss 暫存器中也相同:當系統從使用者模式切換到核心模式時,必須確定 ss 暫存器包含核心資料區段的分段選擇器

  24. 硬體分頁支援(1) • 分頁單元: • 把線性位址轉成實體位址 • 檢查存取的類型是否與線性位址提供的存取型態不一致 • 若記憶體存取不合法分頁錯誤 • 視主記憶體為許多固定長度的頁框集合(頁框又稱為實體頁) • 每個頁框包含一個分頁 • 分頁代表一個區塊的資料,可儲存在頁框中或磁碟中

  25. 硬體分頁支援(2) • 分頁表: • 將線性位址轉換實體位址的資料結構 • 儲存在主記憶體中 • 分頁單元啟動時,核心會初始化分頁表 • Intel 處理器中,藉由設定 cr0 暫存器中的 PG 旗標啟動分頁功能 • 當 PG 數值未設定(其值為 0),表示線性位址會直接被當成實體位址解譯(分頁功能未啟動)

  26. 硬體分頁支援(3) • 分頁: • Intel 處理器中的分頁單元可處理 4KB 大小的分頁 • 32 位元的線性位址分成 3 個欄位: • 最高 10 個位元為目錄;中間 10 個位元為表格;最低的 12 個位元為頁偏移 • 線性位址轉換有兩步驟,每個步驟都需要一個轉換表格,第一:分頁目錄,第二:分頁表 • 分頁目錄: • 起始實體位址儲存在 cr3 行程暫存器 • 目錄欄位:決定參考分頁目錄中的哪一個項目 • 表格欄位:決定要參考分頁表中的哪一個項目,包含某個頁框的實體位址 • 頁偏移欄位:決定在頁框中的相對位置 • 因為頁偏移有 12 個位元,故每個分頁可含 4096 個位元組

  27. 線性位址 31 22 21 12 11 0 目錄 表格 頁偏移 分頁 分頁表 + 分頁目錄 + + cr3 Intel 80x86 下的分頁法

  28. 硬體分頁支援(4) • 目錄與表格欄位都使用 10 個位元,故分頁目錄與分頁表可含 1024 個項目 • 一個分頁目錄可以定址 1024 × 1024 × 4096 = 232記憶體儲存格 • 分頁目錄與分頁表具有相同的結構,包含下列欄位: • 出現旗標: • 旗標為 1 :表示此分頁已載入到主記憶體 • 旗標為 0 :表示此分頁不在主記憶體中 • 存取旗標: • 分頁單元存取過某頁框後,存取旗標會被設定 • 分頁單元不能對此旗標作重設,只能透過作業系統

  29. 硬體分頁支援(5) • 修改旗標: • 只在分頁表中使用 • 當頁框被寫入,會設定此旗標;在作業系統選擇某頁進行替換時,會使用到此旗標 • 分頁單元不能對此旗標作重設,只能透過作業系統 • 讀寫旗標: • 指定分頁或分頁表的存取權限(讀取/寫入或讀取) • 權限旗標: • 指定存取分頁或分頁表所需的權限等級

  30. 硬體分頁支援(6) • PCD 和 PWT 旗標: • 用在硬體快取 • PCD 指示存取頁框中的資料時是否使用快取 • PWT 指示用何種策略將資料分頁寫入頁框 • 策略:寫回或寫穿 • 當 PCD 與 PWT 都設為 0 ,表示快取啟動且採用寫回策略 • 分頁大小旗標: • 只在分頁目錄中使用 • 此旗標設為 1 :在分頁目錄中參考到 4MB 大小的分頁

  31. 硬體分頁支援(7) • 延伸分頁: • Intel 從 Pentium 處理器開始支援 • 允許頁框的大小為 4KB 或 4MB • 延伸分頁的模式下,分頁單元把 32 位元的線性位址分成兩欄位 • 最高的 10 個位元為目錄,剩餘 22 個位元為頁偏移 • 使延伸分頁與一般分頁共存,可設定 cr4 暫存器中的 PSE 旗標 • 使用大塊區域的線性位址對應到實體位址 • 核心不需要再透過中間層的分頁表,可節省中間分頁表的空間;但可能增加內部斷裂

  32. 線性位址 31 22 21 0 分頁目錄 頁偏移 4 MB的分頁 分頁目錄 + + cr3 延伸分頁

  33. 硬體分頁支援(8) • 硬體保護機制: • Intel 處理器中允許分段利用權限旗標來設定 4 種存取權限等級 • 只有 2 種用在分頁與分頁表中 • 若權限旗標為 1:該頁可隨時被存取 • 若為 0,只有在 CPL 小於 3 的權限下才能存取 • 分段有 3 種存取權限(讀取、寫入與執行) • 分頁只有 2 種存取權限(讀取與寫入) • 假設分頁目錄或分頁表裡的讀寫旗標為 0,表示對應的分頁表或分頁只能讀取;否則可讀取或寫入

  34. 硬體分頁支援(9) • 三層式分頁: • 32 位元的架構,採用兩層式分頁法 • 64 位元的架構,採用三層式分頁 • 分頁大小為 16 KB,可定址 214個位址 • 頁偏移欄位用 14 個位元,剩餘 50 個位元分配給目錄欄位與表格欄位;不該浪費如此大空間儲存分頁目錄與分頁表 • Compaq’s Alpha 處理器 • 64 位元的架構,採用三層式分頁 • 每個頁框大小為 8KB,頁偏移欄位為 13 個位元 • 系統只用最低的 43 個位元,剩餘的 21 個較高位元被設為 0 • 剩下的 30 個位元可平均分配成三個 10 位元的欄位(全域目錄、中間目錄與表格)

  35. 分頁 分頁表 分頁中間目錄 + 分頁全域目錄 + + + cr3 線性位址 全域目錄 中間目錄 表格 頁偏移 Linux 中分頁的模式

  36. Linux 上的分頁(1) • Linux 採用三層式分頁 • 全域分頁目錄、中間分頁目錄與分頁表 • 也適用 64 位元的架構 • 全域分頁目錄:包含多個中間分頁目錄的位址 • 中間分頁目錄:包含多個分頁表的位址 • 分頁表中的項目均會指到一個頁框 • 故線性位址被分成 4 個欄位 • 每個欄位使用多少位元,必須視電腦的硬體架構而定

  37. Linux 上的分頁(2) • 行程擁有各自的全域分頁目錄與數個分頁表 • 行程發生內文切換,核心把 cr3 暫存器的內容儲存到 TSS 分段中 • 載入另一個 TSS 分段的內容到 cr3 中 • 當新的行程恢復執行,分頁單元才能指到正確的分頁表 • Linux 應用在 32 位元的架構上,不使用中間分頁目錄,但仍保留它使得相同的程式碼可以在 32 位元或 64 位元的架構下執行 • 核心設計把中間分頁目錄的大小設為 1,使記憶體模型設計與處理器無關

  38. Linux上的分頁(3) • 分頁表的處理: • Linux 核心原始碼中的 asm/page.h 與 asm/pgtable.h 中定義讀取及修改分頁表與分頁目錄時所需的資料結構、函式與巨集,供分頁表進行處理,如型態轉換、讀取或修改分頁表中的項目、查詢分頁表中某項目的旗標狀態或數值、從分頁表的項目中取出分頁位址等 • 全域分頁目錄、中間分頁目錄與分頁表內的項目都是 32 位元的資料型態 • 還有一個 32 位元的資料型態用來表示某個單一項目的保護旗標

  39. Linux上的分頁(4) • 分頁表會儲存在頁框中;每個行程會使用多個分頁表 • 頁框的分配與釋放耗時 • 當核心用完一個分頁表後,會把分頁表所使用的頁框加入到一個軟體快取中 • 當核心下次要建立新的分頁表時,直接由從軟體快取中取得一個頁框 • 只在軟體快取為空,才向系統要求配置一個新頁框

  40. Linux上的分頁(5) • 分頁表快取採用是軟體快取,沒有硬體空間的限制 • 核心必須實作一機制來限定快取所使用的空間,並設定快取使用的上限與下限 • 在系統閒置、或核心釋放一個行程所擁有的分頁表時,系統會檢查每個快取所使用的空間是否超過上限,若超過便會釋放快取中的頁框,直到快取所使用的空間達下限為止

  41. Linux上的分頁(6) • 保留頁框: • 核心程式碼與資料結構儲存於此 • 不能被動態地分配或置換到磁碟中 • Linux 核心會被安裝在實體記憶體位址為 0x00100000 處 • 核心所需要的頁框總數會少於 2MB • 核心不載入到 0x00100000 之前的記憶體空間之因? • 考慮個人電腦結構上的特性: • BIOS 使用第 0 個頁框來儲存系統硬體上的設定 • 從 0x000a0000 到 0x000fffff 的實體位址保留給 BIOS 函式使用 • 有些特殊的電腦硬體會使用到第一個可用的 1MB 空間 • 為了避免將核心載入到不連續的頁框,Linux 不用記憶體中第一個 1MB 的空間

  42. 不可使用頁框 0 1 0x100 0x1ff 可使用頁框 核心程式碼 初始化核心資料 未初始化核心資料 _text _etext _edata _end i386_endbase 記憶體中前2MB 的空間分佈

  43. 第十章 記憶體管理實作 • 記憶體定址 • 頁框管理 • 頁框運作 • 對偶式系統演算法 • 記憶體區域管理 • 摘要

  44. 頁框管理 • Linux 中採用的頁框大小單位是 4KB • 硬體分頁電路在進行位址轉換時,會自動檢查頁框中是否有分頁存在;每個頁框透過分頁表中的各種旗標來達到硬體保護 • 4KB 是大部分磁碟區塊大小的倍數,選擇 4KB 作為頁框大小,容易知道分頁單元在位址轉換的過程中哪裡發生分頁錯誤 • 在主記憶體與磁碟間傳輸資料時較有效率

  45. 頁框運作(1) • 頁框管理: • 核心須記錄每個頁框目前的狀態;核心也須知道在動態記憶體中的頁框是否在使用 • 狀態資訊保存在描述器陣列中;每個頁框對應到一個陣列元素 • 頁框描述器結構如下: • count 變數設為 0 :表示對應的頁框未被使用;如果數值大於 0,表示此頁框被分配給一個以上的行程、或是用來儲存核心資料結構

  46. 頁框運作(2) • list 為一環狀雙向鏈結串列 • 變數 flags:表示目前頁框的狀態 • 指標 next_hash 與 pprev_hash :參考在雜湊串列表 page_hash_table 中的相對分頁 • 當行程要讀取某個檔案的分頁,系統先檢查雜湊表,確定該分頁是否已在快取中 • buffer 指標:指向此分頁所在的快取緩衝區

  47. 頁框運作(3)

  48. PG_locked 表示此分頁需要被鎖定在記憶體中進行磁碟I/O。當I/O 開始時此位元會被設定為1,I/O 結束後此旗標會被清為0。 PG_error 表示此分頁有磁碟I/O 錯誤發生。 PG_referenced 此旗標表示此分頁被配置並曾被存取。 PG_uptodate 除非磁碟的I/O發生錯誤,不然此旗標會在完成磁碟讀取操作後被設定為1。 PG_dirty 此旗標用來表示此分頁是否需要被寫回磁碟。 PG_unused 未使用。 PG_lru 此旗標表示此分頁目前被存放在系統的active list或是 inactive list 之中。 描述頁框狀態的旗標(1)

  49. PG_active 此旗標表示此分頁正被行程所使用(存放在系統的 active list 之中)。 PG_slab 表示此分頁正被slab allocator 所使用。 PG_skip 此旗標用在sparc/sparc 64 架構下已忽略部分的位址空間。 PG_highmem 表示此分頁被載入到高核心位址空間。 PG_checked 表示此分頁只能被EXT2 檔案系統所使用。 PG_arch_1 硬體結構上特定的分頁狀態旗標,當此分頁首次加入快取時,該旗標會被設為0。 PG_reserved 表示此頁框會保留給核心程式碼使用、或是根本不能使用,此旗標被設定的分頁不能被換出記憶體。 PG_launder 當某分頁要被換出記憶體時此旗標將被設定,表示此分頁正被虛擬記憶體寫回。 描述頁框狀態的旗標(2)

  50. 頁框運作(4) • 所有頁框描述器均儲存在 mem_map 陣列中 • 每個頁框描述器均小於 64 位元組, 1MB 的記憶體需 4 個頁框來儲存 mem_map 陣列 • MAP_NR 巨集以頁框位址當參數去計算頁框的號碼,用此號碼當 mem_map 陣列的索引 • 系統透過 free_area_init() 函式初始頁框描述器 • 此函式 2 個參數 • start_mem :在核心保留動態記憶體的起始線性位址 • end_mem :為動態記憶體最終的線性位址加 1 • 利用 i386_endbase 變數儲存保留頁框的初始位址;分配適當大小的記憶體區塊給 mem_map 陣列使用 • 除了 PG_reserved 與 PG_DMA 旗標外,陣列中所有的欄位初始皆設為 0

More Related