Modern Operating System Kernels 第五組報告 1 目錄 • 4.1 記憶體管理概述 4.1.1 4.1.2 4.1.3 4.1.4 分頁式記憶體管理 Segmentation 記憶體管理演算法介紹 Windows記憶體管理概述 • 4.2 Windows系統記憶體管理 4.2.1 系統位址空間初始化 4.2.2 系統位址空間記憶體管理 系統非分頁集區的管理演算法 系統分頁集區的管理演算法 2 4.1記憶體管理概述 資工4A 郭濬愷 3 實體位址(physical address) • 系統的記憶體的真正位址 • 一個32位元或36位元的不帶正負號的整數 4 虛擬位址(virtual address) 虛擬記憶體讓各程序共享系統記憶體空間, 這樣系統就 似乎有了更多的記憶體。 • 優點 擴大位址空間 記憶體保護 記憶體映射 公平分配記憶體 虛擬記憶體共享 5 6 邏輯位址(logical address) • 包含兩個個部分:區段(segment)和偏移(offset) • 邏輯位址的實際位址是區段基址加上偏移量 7 8 分頁式記憶體管理 資工四A 黃柏皓 965002019 9 Intel x86 Address Translation Logic Address Segmentation Virtual Address Paging Physical Address 10 Introduction • 虛擬位置 實體位置 • page page frame • 連續 不一定 11 Virtual Address Form • 32bits • Intel x86 31 Index Offset 分頁表目錄 Index 分頁表 Index 22 21 Offset 12 11 0 12 Address Translation(Intel x86) 10 分頁表目錄 Index(PDE) 10 分頁表 Index(PTE) 12 Offset ●●●● 二級分頁表結構 CR3 優點: 節省page table x1024 ………… …… x1024 缺點: 效能降低 x1024 13 TLB (Translation look-aside buffer) • 快取位址轉譯資訊 o 成功 : 直接取出儲存的位址資訊(TLB) o 失敗 : 兩次存取記憶體(TLB, Page table) • 記憶體存取有區域性 • 硬體處理 o 切換CR3暫存器 o invlpg 指令 (Intel x86 Pentium Pro) 14 15 Address Translation • Virtual→physical CPU Data Memory • Page fault問題 V A • 多對一 TLB TLB miss Program Space Page fault Page Table – 4G VM / 1G PM • 共用問題 – 寫入 Disk 16 Address Translation • Page fault o Random o LRU • 寫入記憶體 o Write-through o Write-back 17 PAE(Physical Address Extension) • 三級分頁表 • 分頁表目錄、分頁表 每一個Entry大小 : 64 bits o 每個page(分頁目錄、分頁表)只能存放512項 o 實體位置描述 : 20bits→24bits(包含12個flag bits) o 可支援:2^(24+12) bits = 2^36 bits = 64 GB (windows : 使用26bits表示→256GB) 18 PAE-Address Translate 分頁表目錄 指標Index 分頁表目錄 Index(PDE) 30 29 31 21 分頁表 Index(PT E) 20 12 Offset 11 0 64bits 24bits PA x512 x512 x512 … … … 4*512 4*512*512 4 19 PAE Example(pae.asm) push push ebx esi mov mov ebx, [esp] + 16 ecx, [esp] + 20 mov esi, [esp] + 12 ; ebx = NewPteContentsedx lowpart ; ecx = NewPteContents highpart eax esi esi ; esi = PtePointer ebx ebx mov edx, [esi] + 4 ecx New esi ebx mov eax, [esi] ; edx:eax = OldPteContents esi esi+4 New PTE lock cmpxchg8b qword ptr [esi] ; compare and exchange jnz pop pop short swapagain esi ebx ; if z clear, exchange failedNew PTE edx eax ecx ebx 20 PAE Summary • 沒有增加virtual memory大小 • 增加可支援的physical memory • Windows(64bits in Intel x64): o 48bits Virtual Mem → 40bits Physical Mem(1TB) 21 Segmentation 資工四A 許木炘 22 Logic address 邏輯位址 Segment(節區) • a16-bit segment selector (segment identifier) Offset(偏移量) • a 32-bit offset within the segment identified by the segment selector 23 Segment selector 24 segmentation register • 為了讓segment selector能被快速取出 -> segmentation register cs: 指向 code segment # (cpl 0 or 3) ss: 指向 stack segment ds: 指向 data segment. es, fs, and gs: 一般用途,可以參用到任何data segment 25 Segment Descriptors • 每個segment可用一個8byte的descriptor表示,每個 segment descriptor會儲存在 ->GDT(global descriptor table) 或 ->LDT(local descriptor table) 26 Segment Descriptors • Base field (32): the linear address of the first byte of the segment. • G granularity flag (1): 0 (byte); 1 (4K bytes). • Limit field (20). • S system flag (1): 0 (system segment); 1 (normal segment). • Type field (4): segment type and its access rights. • DPL (Descriptor privilege level) (2): • Segment-present flag • D/B flag • Reserved bit • AVL flag 27 常用的segment descriptor • Code Segment Descriptor. • Data Segment Descriptor. o P.S.: Stack Segments are implemented by means of Data Segment Descriptors. • Task State Segment Descriptor (TSSD) o A TSSD describes a Task State Segment (TSS) which is used to store the contents of a process registers. • Local Descriptor Table Descriptor (LDTD) 28 29 Segment Registers • Each segment register contains a segment selector. 13-bit index 1-bit TI (Table Indicator) flag. 2-bit RPL (Requestor Privilege Level) • The cs register’s RPL also denotes the current privilege level of the CPU. • 0 represents the highest privilege. 0 represents the kernel mode and 3 represents the user mode. • Associated with each segment register is an additional nonprogrammable register which contain the segment descriptor specified by the segment selector 30 快速存取segment descriptor 31 Locate the Segment Descriptor Indicated by Segment Selector • address=(gdtr/ldtr) + index*8. • GDT的第一個欄位永遠試設為 0. • 能儲存在GDT的節區描述器最大的數目為8191 2^13 - 1 32 Segmentation unit 33 記憶體管理 演算法介紹 34 • 就本質而言,記憶體管理演算法可以分為兩大類 o 點陣圖標記法(Bitmap) o 空間串列法(AV List) 35 點陣圖標記法(Bitmap) • 假設要分配的記憶體大小為 N bytes,而一個 blocks為M bytes,並且符合下列等式N=K*M 也就是說現在共用K個blocks要做動態管理! • 點陣圖標記法:使用K個Bits的Bitmap來記錄這個 K個blocks的使用情形 o 0:free o 1:Allocated 36 點陣圖標記法(Bitmap) • 分配:根據請求的大小確定需要多少個連續 memory blocks,然後掃Bitmap是否存在這樣 的連續空間,若有將Bitmap中對應的連續bits設 為1 • 釋放:指定要釋放的記憶體起始位址和大小,將 bitmap對應的連續bits設為0 37 點陣圖標記法(Bitmap) • 此法實作較簡單,但須額外的記憶體負擔,通常為 𝑁 𝑀×8 其中N為記憶體大小,𝑀為𝐵𝑙𝑜𝑐𝑘大小 • 若請求的記憶體大小不為M的倍數則會有空間浪費,平均 而言會有 M/2 bytes浪費! • 每次分配需要掃瞄bitmap,因為時間複雜度為O(K) 38 空間串列法(AV List) • 首先建立一個空閒串列(Available list) • 在初始時,整個區塊被當作一個大的空閒區塊加 入到空閒串列(Available list),每當記憶體管理 員收到分配請求便從AV list中尋找適合空閒區塊 39 空間串列法(AV List) • 尋找適合的空閒區塊的方法共有以下幾種 first-fit:將list中第一個找到的空閒區塊分配出去 best-fit:從list中找到最接近要求的記憶體大小 之區塊,並將其分配 worst-fit:從list中找最大空閒區塊將其分配 next-fit:從list目前的位置往後掃瞄,找到第一 個符合請求的空閒區塊 40 AV List Example 41 First Fit P3 25K P1 P4 200K P2 200K 缺: • 在串列的前端會產生許多極小的可用空間 (被配置機率 很低) 可用Next-Fit來解決 42 Best Fit P3 25K P2 100K P1 50K P4 250K 缺: 1. 需搜尋完全部串列,才可找到最佳的配置區塊 2. 產生更大量的fragmentation 43 Worst Fit 100K P2 100K 200K P1 P3 P4 25K 44 伙伴系統(Buddy System) • 以2的冪次作為memory的配置單位,假設總 memory size為2𝑘 則宣告 AV[K]的list陣列,陣列 元素 AV[i]記錄了大小為2𝑖+1 的空間串列開頭 • 配置:假設要配置的空間大小為n則求出2𝑖 >n 中i的 最小值,並去av list中尋找k≥ 𝑖的最小解並且AV[K] 不為空串列,若k=i則自AV[K]中取出一區塊並配 置,若K>i則自AV[k]中取出一個block將分為兩 塊(大小皆為2𝑘−1 )將其中一塊加入AV[K-1]的串 列中,另一塊持續切割至大小為2𝑖 時再將其分配 45 • 假設有一個記憶體配置要求為3 Blocks,則 需要22 之block,則此時檢查AV[2],若不 為NULL則配置,否則往下尋找AV[3],直 到不為NULL,切割直到大小相符! 46 伙伴系統(Buddy System) • 分配和回收的時間複雜度皆為O(log n) • 但依然存在外部分散 47 分散(fragmentation) • 分散(fragmentation)共分為兩種 o 外部分散(external fragmentation) 在連續配置的方法下每個free block皆不夠但全部 的free block加總後可以滿足要求的空間,然後因 為不連續所以不能滿足此要求,便稱為外部分散(以 上介紹的演算法皆存在此種問題) o 內部分散(internal fragmentation) 配置出去的空間超過要求的size,兩者之間的差值無 法被有效利用,形成浪費稱為內部分散 48 分頁式記憶體管理系統 (Page memory Management) • 為了解決記憶體的外部分散,我們使用了 分頁式的記憶體方法,而當實體的記憶吃 緊時,我們變要選擇哪些的process該 swap out到disk中哪些該寫入實體記憶 中,而且這個管理方法就稱為 頁面替換演 算法(Page Replacement Algorithm) 49 頁面替換演算法 (Page Replacement Algorithm) • 最佳頁面替換演算法(The Optimal Page Replacement Algoritm) • NRU(The Not Recently Used Page Replacement Algortim) • FIFO(The First-In First-Out Page Replacement Algorithm) • 第二次機會替換演算法(The Second Chance Page Replacement Algorithm) 50 頁面替換演算法 (Page Replacement Algorithm) • LRU(The least Recently Used Page Replacement Algorithm) • NFU(The Not Frequently Used Page Replacement) 51 最佳頁面替換演算法 (The Optimal Page Replacement Algoritm) • 一個理論上的最佳演算法,在這個演算法 理,我們被要求能夠預測每個頁面下次的 使用時間,進而確定最佳替換順序,因為 預測的不可行,所以此為理論不可能實 作,但常用來與其他演算法比較! 52 The Optimal Page Replacement Algorithm Example back 53 最近未使用頁面替換演算法 (The Not Recently Used Page Replacement Algortim) • 存取位元R • 修改位元M • 此 2 位元(R, M)有下列 4 種組合,依據順序進行替換 o (0, 0):表示最近沒有被行程使用,也沒有被行程修改,是最佳 的替換分頁 o (0, 1):表示最近沒有被行程使用,但是已經被修改過,此分頁 須先寫回磁碟後,才可進行替換 o (1, 0):表示最近曾被行程使用,但是沒被修改過,由於可能再 次被使用,故盡量不要替換此分頁 o (1, 1):表示最近曾被行程使用,也被修改過,所以需寫回磁碟 中,是最差的替換分頁選擇 • Back 54 先進新出演算法 (FIFO) • 顧名思義,此演算法就是將最先寫入記憶 體的頁面替換出去,此演算法的概念是把 待在記憶體中最久的頁面替換出去,但實 際上會造成許多不必要的Swap in 和Swap out,所以在實作上這個演算少被單獨使 用! 55 FIFO Example 56 FIFO 另一缺點 理想情況 Belady’s Anomaly FIFO會引起Belady’s Anomaly的情況 back 57 第二次機會演算法 (The Second Chance Page Replacement Algorithm) • 對於FIFO的改進,每個頁面都多一個存取 位元R,每次頁面被使用時變將存取位元R 設為 1 • 替換時從佇列開頭開始尋找若他的存取位 元R為0,就置換出去,若R=1則將此頁面移 到佇列尾巴,並將R設為0 58 第二次機會演算法 (The Second Chance Page Replacement Algorithm) 最常參考的頁 最先載入的頁 0 3 7 8 12 14 15 18 A B C D E F G H (a) 3 7 8 12 14 15 18 20 B C D E F G H A (b) 參考位元 0 視A如新載入 的分頁 參考位元 1 59 時鐘頁面替換演算法 The Clock Page Replacement Algorithm • 此為第二次機會替換演算法的最佳化,作法是多 一個指標,指在時間上最早加入的頁面,檢查時 從指標指到的位置開始尋找,倘若頁面的存取位 元 R=1只需將指標往下移並將R設成0即可 • 此演算法跟第二次機會替換演算法概念是一模一 樣,只是實作上不同而已! • Back 60 第二次機會頁面替換演算法 (The Second Chance Page Replacement Algorithm) (The Clock Page Replacement Algorithm) A L B C K J D I E 參考位元 0 F H G 參考位元 1 61 LRU (The least Recently Used Page Replacement Algorithm) • 這個演算的概念是當要換出一個頁面時,他會優先考慮最 近不常使用的頁面 • 他的想法是利用紀錄去推算未來可能會被使用的頁面,以 達到Optimal • NRU 和LRU並不一樣!NRU是利用存取位元和修改位元來 做出選擇,而LRU在實作時要求能夠找到最久沒有使用過 的頁面這需要一個頁面串列來實作,也因此這個演算法 Cost高,且難以靠硬體實作! 62 LRU Example Back 63 NFU (The Not Frequently Used Page Replacement) • 這個演算法的概念與LRU一致,他主要是提供了一種軟體 實作。 • 作法是對一個Page 都擁有一個Counter,而每當時鐘中 斷時,便將每個page的存取位元 R之值(0 or 1)加到 Counter上,所以經常被使用的Page 之Counter值會比 較大,反之Counter較小 • 然而因為此演算法的Counter的值只增不減,會成歷史會 永久影響替換演算法的決策! 64 頁面老化演算法 Page aging algorithm • 此為對NFU演算的的改進版 • 作法是每次時鐘中斷時,將Counter的值右移 一個Bit並將存取位元R加到最左邊的位元上 • 由於此演算法的Counter的Bit是有限的,所以 並不是相當精準,但能消除歷史的影響! 65 工作集 Working Set • 程式執行時,對於存取的memory area 並非均 勻的,而是具某種集中/局部存取的特性 • 而一段時間內所存取的Page 變稱為「工作集」 • 我們記錄工作集穩定下來某一時刻的工作集,當 下次該process被啟動時直接為這些page賦予實 體記憶體進而加快啟動速度。Windows將這種最 佳化手段稱為 Logical Prefetcher 66 工作集 Working Set • 工作集在實作上一種簡單的作法就是記錄每個頁 面最近被存取的時間,根據預設時間 t,一旦目前 時間超過某頁面最近被存取的時間再上 t 則將該 頁面去除 • 利用Working set我們可以改良上述的替換演算 法;如時鐘替換演算中如果目前的指標指到的 page的存取位元為0,則該被置換,但加上 working set後才需考慮此page是否屬於 working set 67 4.2 Windows 系統記憶體管理 975002538 資工4B 江瑞敏 68 Outline • • • • 1. windows memory 初始化 phase 0 2. windows memory 初始化 phase 1 3. 非分頁集區管理演算法 4. 分頁集區管理演算法 69 windows memory 初始化 phase 0 70 Windows 開機流程 71 ntldr • 1. 初始化系統的環境,讓windows kernel可以從 protected mode 的情況下開始執行。 • 2. ntldr 可以拆成兩個部分: o Real mode code o PE format code • 3. Segmentation 在 Real Mode code 初始化 • Paging 在 Protected Mode 初始化 72 Windows Segmentation - Init - lgdt 0x15a8 …….. Movl %cr0, %eax Or $0x01, %eax Mov %eax, %cr0 73 Windows Segmentation(cont.) • • • • 1. CS:0x8 2. SS:0x10 3. DS, ES:0x23 4. FS:0x30 74 Windows Segmentation(cont.) selector Descriptor address Descriptor content Segment Maximum base addr Offset CS 0x8003f008 Ffff 0000 9b00 00cf 0x0 0xfffff000 SS 0x8003f010 Ffff 0000 9300 00cf 0x0 0xfffff000 DS ES 0x8003f020 Ffff 0000 f300 00cf 0x0 0xfffff000 FS 0x8003f030 0001 f000 93df ffc0 0xffdff000 0x00001000 75 Windows Segmentation Conclution • 1. Windows 並沒有使用 Segmentation 的機制。(Same as Linux) • 2. 除了FS這個register以外,其他segment registers 都是從0到4GB。 76 Paging - Init • • • • • mov eax, [page_directory] mov cr3, eax mov eax, cr0 or eax, 0x80000000 mov cr0, eax 77 Translation table mapping 16MB pfn 400 800 100 1000 … … pa PDE 0x200 0x80000000 0x300 … … 78 KiSysemStartup • KiSysemStartup -> KiInitializekernel 在啟動處理器 ( P0 ) 上執行全域範圍的核心初始化 • KiInitializekernel -> ExpInitializeExecutive 對執行體進行初始化 • ExpInitializeExecutive -> MmInitSystem 初始化執行體子元件 • e.g. , 記憶體管理員 79 MmInitSystem - Introduction • 1. MmInitSystem 主要分成三個階段: Phase 0 Phase 1 Phase 2 80 重要的資料結構 • • • • • 1. MMPTE 2. MMPTE_HARDWARE 3. LOADER_PARAMETER_BLOCK 4. MM_FREE_POOL_ENTRY 5. MEMORY_ALLOCATION_DESCRIPTOR 81 MMPTE 82 Page table format(intel manual) 83 MMPTE_HARDWARE 84 與page table 相關的macro 85 Windows Page Table Self-Mapping • 1. Windows 用一個非常獨特的方法去管理Process 的 page table • 2. 一般情況下系統需要4mb+4kb的大小來儲存整個 translation table • 3. Windows 指使用了4mb來儲存,並且運用自對應的技 巧,以及位置的設定,使其能更容易得取得page directory 和 page table 的virtual address Windows Page Table Self-Mapping 0xc0000000 4mb PDE 0xc0030000 Page table 0x0 0x1 0x2 ……… 0x300 ….. ….. ….. PDE 0xc0030000 ……… PDE …….. ….. …… ….. 0xc0040000 Virtual address 0xc0000000 Page Tabe 4MB 0xc0040000 _LOADER_PARAMETER_BLOCK 88 _MMFREE_POOL_ENTRY 89 _MEMORY_ALLOCATION_DESCRIPTOR 90 List Entry 91 RemoveTailList Listhead B F Entry = ListHead>Blink; Blink = Entry->Blink; ListHead->Blink = Blink; Blink->Flink = ListHead; Blink B F B F Entry B F 92 RemoveHeadList Entry B F Entry = ListHead>Flink; Flink = Entry->Flink; ListHead->Flink = Flink; Flink->Blink = ListHead; return Entry; Flink B F Listhead B F B F 93 InsertTailList Listhead B F Blink = ListHead->Blink; Entry->Flink = ListHead; Entry->Blink = Blink; Blink->Flink = Entry; ListHead->Blink = Entry; Blink B F B F Entry B F 94 InsertHeadList Entry B F Flink = ListHead->Flink; Entry->Flink = Flink; Entry->Blink = ListHead; Flink->Blink = Entry; ListHead->Flink = Entry; Flink B F Listhead B F B F 95 CONTAINING_RECORD • • • • 1. List_Entry 是一個double link list 2. 在Windows 的設計中,List_Entry可以指向不同的data structure. Ex. Foo Bar List_Entry Flink Blink List_Entry Flink Blink CONTAINING_RECORD • #define CONTAINING_RECORD(address, type,field) • ((type *)( (PCHAR)(address) – • (ULONG_PTR) (&((type *)0)->field))) Structure Base address name (20 bytes) offset teacher (20 bytes) student (4 bytes) address list_entry flink blink 97 Phase 0 • 1. Phase 0 的目的主要是將系統的Global Variables 做初始化的動作。 • 2. MmInitSystem 主要的功能便是初始化一些系 統Global Variables • 3. MiInitMachineDependent 主要的功能是讓 Windows 的Virtual Address System 運作起來。 98 MiInitMachineDependent – Phase 0 • 1. 紀錄 cr3 到 current process • 2. 計算系統總共的free memory • 3. 調整全域變數MmSizeOfNonPagedPoolInBytes and MmMaximumNonPagedPoolInBytes • 4. 計算MmNonPagedPoolStart 的位置 • 5. 計算那些區塊需要使用大分頁對應(如PFN資料庫, Kernel code等等),以供phase 1 使用 • 6. 分配系統PTE和擴充的非分頁集區位置 • 7. 初始化非分頁集區以及分頁集區資料結構 99 MiInitMachineDependent 0 • • • • 將PDE 的 base addresss 記錄到current process。 Current Process 為 Idle Process PDE_BASE = 0xC0300000 DirBase = PdePageNumber 10 MiInitMachineDependent 1 • 將Idle Process 0~2GB 的virtual address space 設置為0 • KSEG0_BASE = 2GB • P.S 0~2GB 是 user space 在 idle process並不 會用到 10 Find Free Memory Space 102 Find Free Memory Space (cont.) 103 Find Free Memory Space (cont.) • 當這個步驟完成以後,以下的Global Variables 就會被設定好。 • MmNumberofPhysicalPages • MmLowestPhysicalPage • MmHighestPhysicalPage • MxFreeDescriptor 104 分頁表的對應 • 分配系統PTE和擴充非分頁集區位置範圍的分頁表 105 MiInitializeNonPagedPool - intro • 1.初始化MmNonPagedPoolFreeListHead • 2. 將MMPTE_POOL_ENTRY FirstEntry Inset 到 MmNonPagedPoolFreeListHead[index]中 • 3. 將其餘的FreeEntry owner field 指到 FirstEntry • 4. 紀錄MiStartOfInitialPoolFrame 以及 MiEndOfInitialPoolFrame MiInitializeNonPagedPool 0 • 初始化MmNonPagedPoolFreeListHead • MI_MAX_FREE_LIST_HEADS = 4; 107 MiInitializeNonPagedPool 0 3 Flink Blink 2 Flink Blink 1 Flink Blink • MmNonPagedPoolFreeListHead 0 Flink Blink MiInitializeNonPagedPool 1 109 MiInitializeNonPagedPool 1 List Size Signature owner MMPTE_POOL_ENTRY FirstEntry = FreeEntry • 3 Flink Blink 2 Flink Blink MmNonPagedPoolFreeListHead 1 Flink Blink 0 Flink Blink MiInitializeNonPagedPool 2 • 將空閒頁面串聯起來 111 List Size • •List Signature owner FreeEntry Size Signature owner FirstEntry List Size FreeEntry Signature owner FreeEntry List Size Signature owner FreeEntry List Size Signature owner FreeEntry • List List Size Signature owner FirstEntry Size Signature owner FreeEntry FreeEntry List Size Signature owner FreeEntry 3 Flink Blink 2 Flink Blink MmNonPagedPoolFreeListHead 1 Flink Blink 0 Flink Blink MiInitializeNonPagedPool 3 設定MiStartOfInitialPoolFrame 114 MiInitializeNonPagedPool 4 設定MiEndOfInitialPoolFrame 115 0x80000000 MmPfnDatabase MmNonPagedPoolStart MiSystemCacheStartExtr MiMaximumSyste a mCacheSizeExtra( 個頁面) MiSystemViewStart MmSeesionBase 0xc0000000 0xc0400000 MmSystemCacheWorkin gSetList MmSystemCacheStart MmPagedPoolStart MmNonPagedSystemSta rt MmNonPagedExpansio nStart 0xffbe0000 核心、HAL等系統模 組的映象區 PFN 資料庫 非分頁集區 系統快取額外區 系統PTE額外區 系統檢視 工作階段空間 分頁表 超空間和行程工作集 系統快取結構 系統快取 分頁集區 系統PTE區域 非分頁集區擴充區 當機轉存區 0xffffffff 保留區 116 全域變數名 典型取值 全域變數名 典型取值 MmHighestUserAddress 0x7ffeffff MiSessionImageStart 0xbf800000 MmUserProbeArresss 0x7fff0000 MiSessionImageEnd 0xc0000000 MmSystemRangeStart 0x80000000 MmSystemPteBase 0xc0000000 MmPfnDatabase 0x81000000 MmWorkingSetList 0xc0502000 MmNonPagedPoolStart 0x81301000 MmHyperSpaceEnd 0xc0bfffff MmNonPagedPoolEnd0 0x82000000 MmSystemCacheWorkingSetList 0xc0c00000 MiSystemCacheSizeExtra 0x82000000 MmSystemCacheStart 0xc1000000 MiMaximumSystemCacheSizeExtra 0x2f800 MmpagedPoolStart 0xc1000000 MiSystemViewStart 0xbb000000 MmpagedPoolEnd 0xf0bfffff MmSessionBAse 0xbc000000 MmNonPagedSystemStart 0xf0c00000 MmSessionPoolStart 0xbc000000 MmNonPagedPoolExpansionStart 0xf8ba0000 MiSessionViewStart 0xbc400000 MmNonPagedPoolEnd 0xffbe0000 MisessionSpaceWs 0xbf400000 MmNumberOfPhysicalPages 0x0001ff7a 117 Windows memory 初始化 phase 1 & 非分頁集區管理演算法 975002536 資工4B 張嘉顯 118 Phase1 – 流程 • MiInitMachineDependent • 設定全域變數MmSharedUserDataPte • 初始化工作階段空間 o MiSessionWideInitializeAddress o MiInitializeSessionWsSupport o MiInitializeSessionIds • 啟動平衡集管理員 o KeBalanceSetManager o KeSwapProcessOrStack 119 MiInitMachineDependent – Phase1 • 全域陣列MiLargeVaRanges紀錄要轉成大頁面的區域 • 可能包涵 核心本身映像區、PFN資料庫、非分頁集區 120 MxConvertToLargePage 121 MxConvertToLargePage • 將PTE整合成一個大頁面(4MB) 122 Phase1 - MmSharedUserDataPte • MmInitSystem向分頁集區申請一個PTE • MmSharedUserDataPte指向該PTE • 對應到0xffdf0000 123 Phase1 – 0x7ffe0000 • 將0x7ffe0000和0xffdf0000對應到同一個實體頁面上 124 為什麼要對應到同一個實體頁面 • 使用者模式程式碼可以存取系統的一些狀態資料, 如process的資訊或thread的資訊 • Windows software interrupt(SYSENTER)時也會 用到此區域 125 非分頁集區 • 使用MiAllocatePoolPages、MiFreePoolPages 申請和歸還頁面 • 包凡系統PTE區域、非分頁集區擴充區 • 永遠都有實體的記憶體與之對應 126 127 Allocation 流程 • 1. Loop 過 MmNonPagedPoolListHead[index] • 2. 如果其中一個index的FirstEntry Size field 夠大的話, 便分配那個區段並回傳其virtual address • 3. 如果Size field > 需求的頁面,便會將後面的freeEntry 分配出去 • 4. 並且重新計算總共有幾個頁面,並且鍵結到相對應的 MmNonPagedPoolListHead[index] 現在總共有連續的六個頁面 使用者需求三個 從index 2開始找起直到找到足夠的頁面 由於index 2 沒有東西,所以從index 3去抓取頁面 Index 3 的FirstEntry 有六個頁面, Page Size > Require Page 分配後面三個頁面給使用者 由於只剩下三個連續頁面,所以便link到index 2 3 Flink Blink 2 Flink Blink MmNonPagedPoolFreeListHead 1 Flink Blink 0 Flink Blink MiFreePoolPage 流程 • 1. 判斷歸還的頁面數目以及位置是否與現有的Virtual Address連續 o True: 將頁面合併,並且鍵結到相對應的MmNonPagedPoolListHead[index] index = 合併後的頁面數目 - 1 o False: 將歸還的頁面,鍵結到相對應的MmNonPagedPoolListHead[index] index = 歸還的頁面數目 -1 系統回收兩個頁面 判斷與現有的頁面是否連續 3 Flink Blink 2 如果不連續 回收的頁面,鍵結到相對應的 MmNonPagedPoolListHead[index] Index = 回收頁面 - 1 Flink Blink MmNonPagedPoolFreeListHead 1 Flink Blink 0 Flink Blink 系統回收兩個頁面 判斷與現有的頁面是否連續 如果連續 將回收的頁面與原本的頁面結合 並將結合完的頁面鍵結到相對應的 MmNonPagedPoolListHead[index] Index = 回收頁面 - 1 3 Flink Blink 2 Flink Blink 1 Flink Blink 0 Flink Blink 系統分頁集區的管理演算法 975002530 資工4B 林賢勁 133 0x80000000 MmPfnDatabase MmNonPagedPoolStart MiSystemCacheStartExtr MiMaximumSyste a mCacheSizeExtra( 個頁面) MiSystemViewStart MmSeesionBase(0xbc00 0000) 0xc0000000 0xc0400000 MmSystemCacheWorkin gSetList MmSystemCacheStart MmPagedPoolStart MmNonPagedSystemSta rt(0xf0c00000) MmNonPagedExpansio nStart 0xffbe0000 核心、HAL等系統模 組的映象區 PFN 資料庫 非分頁集區 系統快取額外區 系統PTE額外區 系統檢視 工作階段空間 分頁表 超空間和行程工作集 系統快取結構 系統快取 分頁集區 系統PTE區域 非分頁集區擴充區 當機轉存區 0xffffffff 保留區 134 全域變數 • 紀錄分頁集區起始位置 o MmPagedPoolStart (系統全域) 0xe1000000 o MiSessionPoolStart (工作階段) 0xbc000000 • 儲存分頁集區的大小 o MmSizeOfPagedPoolInBytes (大小) o MmSizeOfPagedPoolInPages (Index) MmSizeOfPagedPoolInPages = MnSizeOfPagedPoolInBytes >> PAGE_SHIFT; 135 typedef struct _MM_PAGED_POOL_INFO{ PRTL_BITMAP PagedPoolAllocationMap; PRTL_BITMAP EndOfPagedPoolBitmap; PMMPTE FirstPteForPagedPool; PMMPTE LastPteForPagedPool; PMMPTE NextPdeForPagedPoolExpansion; ULONG PagedPoolHint; SIZE_T PagedPoolCommit; SIZE_T AllocatedPagedPool; }MM_PAGED_POOL_INFO, *PMM_PAGED_POOL_INFO; 136 typedef struct _RTL_BITMAP { ULONG SizeOfBitMap; // Number of bits in bit map PULONG Buffer; // Pointer to the bit map itself } RTL_BITMAP; typedef RTL_BITMAP *PRTL_BITMAP; 137 建立 MmInitSystem call MiBuildPagedPool initialize PagedPoolAllocationMap EndOfPagedPoolBitmap FirstPteForPagedPool LastPteForPagedPool MmPagedPoolInfo ‘s member NextPdeForPagedPoolExpans ion PagedPoolHint PagedPoolCommit AllocatedPagedPool 138 PagedPool位置範圍 • MmPagedPoolStart 0xe1000000 • MmPagedPoolEnd 0xf0bfffff 分別紀錄分頁集區的起始位址與結束位址 PointPte =MiGetPteAddress(MmPagedPoolStart); MmPagedPoolInfo.FirstPteForPagedPool = PointerPte; MmPagedPoolInfo.LastPteForPagedPool = MiGetPteAdress(MmPagedPoolEnd); 139 NextPdeForPage d PoolExpansion 000000… 140 分配與回收 • MiAllocatePoolPages • MiFreePoolPages 141 MiAllocatePoolPages • 依據PoolType參數 去找到記憶體集區 MM_PAGED_POOL_INFO結構 系統分頁集區 (MmPagedPageInfo) 工作階段空間的Paged pool (MmSessionSpace -> PagedPoolInfo) 142 • Call RtlFindClearBitsAndSet 搜尋指定數量的連續零位元 • 如果找到上述的零位元 就paged pool中對應之連續空閒頁面 • 如果無法 NextPdeForPagedPoolExpansion成員往後移 (擴充分頁集區) 143 MiFreePoolPages • 先用PagedPoolInfo中的兩個BitMap做驗證 StartingAddress的有效性 PagePoolAllocationMap EndOfPagedPoolBitmap • 若有效 修改兩個BitMap,並維護PagedPoolInfo->AllocatedPagedPool 和 PagedPoolInfo->PagedPoolCommit • 若無效 • Bugcheck(系統當機) 144 Reference • http://www.geoffchappell.com/studies/windows/k m/cpu/sep.htm • http://wiki.osdev.org/Main_Page • http://www.intel.com/content/www/us/en/process ors/architectures-software-developer-manuals.html