600 likes | 830 Views
系統 PTE 區域的管理. 995202110 洪 彥伯. 系統 PTE 區域的管理. Windows 中整個位址空間中,除了工作階段空間以外,還有一部分的記憶體也是用 ” 動態記憶體 ” 的方式管理的: 系統 PTE 區域 注意:這部分位址範圍稱為系統 PTE 區域,並非表示他存放的是 PTE ,而是表示這段是用 ”PTE 形式 ” 去管理的。 把 PTE 當做資源管理. 系統 PTE 區域的管理. “PTE 區域 ” 在 PTE 中的位址 “PTE 區域 ” 也是一段記憶體位址,因此在 PTE 中也要占有一些 entry 。 0xc0000000
E N D
系統PTE區域的管理 995202110 洪彥伯
系統PTE區域的管理 • Windows中整個位址空間中,除了工作階段空間以外,還有一部分的記憶體也是用”動態記憶體”的方式管理的: • 系統PTE區域 • 注意:這部分位址範圍稱為系統PTE區域,並非表示他存放的是PTE,而是表示這段是用”PTE形式”去管理的。 • 把PTE當做資源管理
系統PTE區域的管理 • “PTE區域”在PTE中的位址 • “PTE區域”也是一段記憶體位址,因此在PTE中也要占有一些entry。 • 0xc0000000 • 與一般page的差異: • 一般頁面有對應的實體記憶體page • PTE區域的頁面在靜止時並沒有對應的實體記憶體page,當取用時才對應到實體頁面。
系統PTE區域的管理 • PTE區域未必按照硬體所定義的PTE格式: 硬體PTE欄位: Typedefstruct _MMPTE_LIST{ ULONG Valid : 1; ULONG OneEntry : 1; ULONG filler1 : 8; ULONG prototype : 1; ULONG filler1 : 1; ULONG NextEntry : 20; } MMPTE_LIST;
系統PTE區域的管理 • 由NextEntry可看出,PTE區域是用list的觀念去管理的。 • PTE串列 • 因為PTE頁面一定對齊4K,所以最後12bit為0,所以只需20bit就可表達PTE區域的一個頁面位址。
PTE串列的概念 • 串列、磁簇(cluster) • 磁簇:連續位址的頁面構成一個磁簇。 • 串列:串列只需要把磁簇的開頭串接起來。
PTE區域的管理 • PTE區域的用途: • I/O、kernel stack等動態對應頁面。 • 管理概觀: • PTE區域是一串很長的串列,每次要取用,就要搜尋整個串列,沒有效率。 • 解決方法:做快取
PTE區域的管理 #define MM_SYS_PTE_TABLE_MAX 5 #define MM_PTE_TABLE_LIMIT 16 ULONG MmSysPteIndex[MM_SYS_PTE_TABLE_MAX] = {1,2,4,8, MM_PTE_TABLE_LIMIT}; UCHAR MmSysPteTables[MM_PTE_TABLE_LIMIT+1] = {0,0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4}; ULONG MmSysPteMinimumFree[MM_SYS_PTE_TABLE_MAX] = {100,50,30,20,20}; PVOID MiSystemPteNBHead[MM_SYS_PTE_TABLE_MAX]; ULONG MmSysPteListBySizeCount[MM_SYS_PTE_TABLE_MAX]; ULONG MmTotalFreeSystemPtes[MaximumPtePoolTypes]; ULONG MmSystemPtesStart[MaximumPtePoolTypes]; ULONG MmSystemPtesEnd[MaximumPtePoolTypes]; MMPTE MmFirstFreeSystemPte[MaximumPtePoolTypes];
PTE區域的管理 • MmSysPteIndex定義5種大小的連續”空PTE區域”頁面區塊。 • 當要申請PTE區段時,只要將欲申請的大小當作index,取出MmSysPteTables中對應的數值即可當作MmSysPteIndex的大小 • MmSysPteIndex [MmSysPteIndex [NumberOfPtes]]
PTE區域的管理 • MiSystemPteNBHead:為每一種大小的連續頁面定義了一個”佇列”。 124816
PTE區域的管理 • MmSysPteMinimumFree:每種大小的頁面的佇列最小值。 • 當某個佇列長度< MmSysPteMinimumFree對應值,系統會從PTE維護的串列中取出區塊加到佇列中。 • 當用戶釋放區塊時,若對應的佇列上有空間,則加入;若無,則收回到維護的串列中。 • 佇列上限(X86):400,200,60,50,40
PTE區域的管理”實作” • 主要函式有:base\ntos\mm\sysptes.c • MiInitializeSystemPtes • MiReserveSystemPtes • MiReleaseSystemPtes
PTE區域的管理”實作” • 流程: • MiInitializeSystemPtes初始化PTE區域 • 初始化PTE單串列,每個node是一塊記憶體,稱做chunk。 • MiReserveSystemPtes會申請一塊很大的PTE區段,然後按小區塊釋放頁面。 PMMPTE NTAPI MiReserveSystemPtes ( IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPESystemPtePoolType ) • SystemPtePoolType:SystemPteSpace, NonPagedPoolExpansion
PTE區域的管理”實作” • MiReserveSystemPtes: • 根據NumberOfPtes決定使用哪種佇列 • 如果佇列區塊數量<預定的最小值 • MmSysPteListBySizeCount<MmSysPteMinimumFree 呼叫MiFeedSysPtePool函式,獲得更多區塊。 • 如果NumberOfPtes>16,或沒辦法取得指定大小區塊。 • 呼叫MiReserveAlignedSystemPtes
PTE區域的管理”實作” • MiReleaseSystemPtes • 要釋放的PTE必須是”無效”的,也就是對應的虛擬位址沒有對應的實體頁面。 • 若釋放的頁面<=16,則會插回MiSystemPteNBHead中,而不會歸還到PTE串列中。 • 若>16,則須歸還到PTE串列中。 • 從MmSystemPtesStart開始搜尋,直到有空間可以插入。
4.3.1 位址空間的建立和初始化 995202014 陳佑宗
行程位址空間的建立 • 呼叫MmCreateProcessAddressSpace函式建立位址空間 • 這裡僅介紹Intel x86版本,其程式碼位於base\ntos\mm\i386\procx86.c檔案的28-362行 BLEEN MmCreateProcessAddressSpace ( IN ULONG MinimumWorkingSetSize , //建立行程的最小工作集的大小 IN PROCESS NewProcess , //建立行程的行程物件 OUT PULONG_PTR DirectoryTableBase //指向行程位址空間的分頁目錄位址 ) ;
行程位址空間的建立-函式流程 • Step 1 確保系統有足夠的分頁檔 MiChargeCommitment ( RealCharge , CurrentProcess ) 在intel x86上需確保4個頁面
行程位址空間的建立-函式流程 • Step 2 確認目前實體頁面是否達到指定的要求 • Step 3 形成分頁目錄頁面 MinimumWorkingSetSize 分頁目錄頁面 分頁框架編號 PageDirectoryIndex //區域變數 實體頁面
行程位址空間的建立-函式流程 • Step 4 形成超空間分頁表頁面 • Step 5 形成VAD點陣圖 超空間分頁表頁面 分頁框架編號 HyperSpaceIndex //區域變數 實體頁面 VAD點陣圖 分頁框架編號 VadBitMapPage //區域變數 實體頁面
行程位址空間的建立-函式流程 • Step 6 工作集串列 • Step 7 初始化Vm.MinimumWorkingSetSize ,WorkingSetPage ,DirectoryTableBase 工作集串列 實體頁面
行程位址空間的建立-函式流程 • Step 8 填寫好對應VAD點陣圖和工作集串列的分頁表項目之後釋放此PTE 超空間分頁表頁面 對應 一個PTE 系統PTE 工作集串列 VAD點陣圖
行程位址空間的建立-函式流程 • Step 9 在PFN資料庫中設置分頁目錄頁面的PTE位址(虛擬位址0xc0300000) • Step 10 把新行程加入到系統內部維護行程串列 MmProcessList EPROCESS MmProcessLinks … …
行程位址空間的建立-函式流程 • Step 11 初始化分頁目錄頁面 之後把4個頁面的負擔紀錄紀 錄至MmProcessCommit中 0xc0000000 分頁目錄頁面 對應 0xc4000000 一個PTE 系統PTE(動作完後釋放) 對應 複製系統空間的PDE (0x80000000開始的位置範圍) 超空間分頁表頁面 (內涵VAD及工作集) PDE (全域變數)
行程位址空間的建立-函式流程 • Step 12 呼叫MiSessionAddProcess函式把新行程加入到新行程的父行程所在的工作階段空間中 • MmInitializeProcessAddressSpace函式被呼叫情況 • 建立新行程時,有記憶體區段物件無位址空間時 • 沒有記憶體物件,類似fork()操作時 • 無記憶體區段物件、無位址空間及行程建立相關的旗標亦為關閉時 • 系統初始化階段,parent為NULL時 新行程 MiSessionSpace(全域變數)
行程位址空間的建立-函式流程 • 接下來呼叫MmInitializeProcessAddressSpace函式初始化使用者空間部分(0x0-0x7fffffff) NTSTSTUS MmInitializeProcessAddressSpace ( INPEPROCESSProcessToInitialize , //要初始化的目標行程 INPEPROCESSProcessToClone OPTIONAL , //新行程的位址空間可從該行程複製獲得 IN PVOID SectionToMap OPTIONAL , //提供一記憶體區段物件,鰾是在新行程位址空間中對應此物件 IN OUT PULONG CreateFlags , //各種與行程建立相關的旗標 OUT POBJECT_NAME_INFORMATION *AuditName OPTIONAL , //物件名稱資訊指標 ) ;
行程位址空間的建立-函式流程 • Step1 判斷是否更新新行程空間中的系統PDE(分頁後半部分),若需要則呼叫MiUpdateSystemPdes • Step 2 呼叫KeAttachProcess把目前緒程”暫時”附加至待初始化的行程物件上 • Step 3 標明目前正在使用位址空間2 • Step 4 初始化位址建立鎖及工作集互斥器 ProcessToInitialize->Flags = PS_PROCESS_FLAGS_ADDRESS_SPACE2 ProcessToInitialize->AddressCreationLock ProcessToInitialize->Vm.WorkingSetMutex
行程位址空間的建立-函式流程 • Step 5 初始化VAD樹並設置最後修剪時間及工作集串列 • Step 6 初始化新行程分頁目錄和超空間分頁表的PNF,以及VAD點陣圖和工作集的PNF • Step 7 初始化新行程工作集串列 • Step 8 若以3GB啟動方式或64位元系統,則需另外建立一VAD,來保留共用的使用者頁面 Vm.LastTrimTime Vm.VmWorkingSetList MiInitializeWorkingSetList
行程位址空間的建立-函式流程 • Step 9 Skip • Step 10 根據系統登錄設置及目前系統環境來確定是否在新行程中由高向低分配虛擬位址空間 • Step 11 建立新行程 MmMapViewOfSection參閱4.3.4 EPROCESS (新行程同樣對應) 1 2 ImageFileName … SectionToMap 記憶體區段物件的可執行映像檔 4 (ntdll.dll對應至新行程位址空間) 3 … PsMapSystemDll (把新行程的虛擬位址空間插入工作管理串列) MiAllowWorkingSetExpansion 5
行程位址空間的建立-函式流程 • Step 12 行程複製 • Step 13 如果是系統行程則什麼也不做 • Step 14 如果新行程是一個複製的行程或系統行程則關閉大頁面建立旗標,則結束函式 檢查目前行程每一個VAD,且根據頁面屬性檢查PTE,並複製到新行程,其複製特性見4.4.4 父行程呼叫MiCloneProcessAddressSpace 複製位址空間後,把新行程虛擬空間位址插入到工作管理集中串中 MiAllowWorkingSetExpansion (PROCESS_CREATE_FLAGS_LARGE_PAGES)
位址空間切換 • 分頁目錄前半是每個行程私有,老的行程切換至新的行程後則完全轉移至新行程位址空間 • 後半為共有,但每個行程分頁目錄頁面是獨立,因此一但切換至新行程後,新位址空間中的PDE項目指向全域的分頁表 • 新行程有可能指向錯誤的分頁集區,產生分頁錯誤,因此利用”延遲計算”來保持分頁集區分頁表對應的一致性 (MmSystemPagePtes記錄了分頁集區的分頁表對應)
位址空間切換 • 另外VAD點陣圖及工作集串列的位址所對應的PDE會指向各自的超空間分頁表頁面 • 因此在行程切換時,只需要直接切換分頁目錄頁面,無須對分頁目錄的PDE做任何調整或一致性維護,除了超空間和工作階段空間部分以外,其他皆能在新老行程中保持一致
4.3.3 行程位址空間的記憶體管理 995202003張嘉文
4.3.3 • User Mode 可用的記憶體空間 : 0x0 – 7fffffff • 要使用一段記憶體位址,必須透過兩步驟 • Reserve • Commit
Virtual Memory • Reserve(保留) • 保留一段記憶體,但不真正使用。 • 不佔用任何實體記憶體。 • Commit(提交) • 真正實際使用記憶體。 • 實際可提交的量 = 全部實體記憶體 + 分頁檔 – 系統使用記憶體
VAD (Virtual Address Descriptor) • EPROCESS MM_AVL_TABLE MMAVL_TABLE* vadRoot MMADDRESS_NODE balancedRoot
MM_AVL_TABLE typedefstruct _MM_AVL_TABLE { MMADDRESS_NODE BalancedRoot; ULONG_PTR DepthOfTree: 5; ULONG_PRT Unused: 3; ULONG_PRT NumberGenericTableElements: 24; PVOID NodeHint; PVOID NodeFreeHint; } MM_AVL_TABLE, *PMM_AVL_TABLE;
MMVAD typedefstruct _MM_MMADDRESS_NODE { union { LONG_PTR Balance : 2; struct _MMVAD * parent; } struct _MMVAD * LeftChild; struct _MMVAD * RightChild; ULONG_PTR StartingVpn; ULONG_PTR EndingVpn; } MMADDRESS_NODE, *PMMADDRESS_NODE;
AVL Tree • VadRoot.BalancedRoot.RightChild [20, 20] [130,134] [270, 2a3] [240,24f] [300, 305] Root [410,50f] [67000, 6700e] [77c50,77cee] [77e40, 77f41] [7c800, 7c8bf] [7ffb0, 7ffd3] [7ffdd, 7ffde]
Base\ntos\mm\addrsup.c • MiFindNodeOrParent () • MiInsertNode() • MiRemoveNode()
VAD點陣圖 • MiInsertVadCharges() StartBit = (ULONG) (((ULONG)MI_64K_ALIGN (MI_VPN_TO_VA(Vad->StartingVpn)))/X64K); EndBit = (ULONG) (((ULONG)MI_64K_ALIGN (MI_VPN_TO_VA(Vad->EndingVpn)))/X64K); VadBitMap.SizeOfBitMap = MiLastMadBit + 1; BadBitMap.Buffer = VAD_BITMAP_SPACE; RtlSetBits (&VadBitMap, StartBit, EndBit – StartBit + 1);
4.4記憶體分頁 995202097 黃彥翔
分類表項目--PTE • 分頁錯誤!!!Why?Why? Why? • 當一個虛擬位置引用時,該位置的分類表項目的有效位為零,則會引發例外。 • Windows核心的trap handler會將此例外交給記憶體管理員的分頁錯誤處理常式,由它解決無效問題。 • BTW,此例外是由硬體觸發的!而分頁錯誤處理常式是OS的元件之一。
實體記憶體很珍貴 • 實體記憶體畢竟是有限的資源,隨著越多的行程會用掉越多的實體頁面。 • 為了避免實體記憶體消耗光,OS提供了分頁的能力,即把正在使用中的的頁面存放到硬碟,將騰出的空間供給他用。 • 當磁碟上的頁面再度被引用時,分頁處理常式再將他們喚回記憶體中。
分頁檔是甚麼? • 分頁檔可看作實體記憶體的延伸。 • 對分頁檔的內容而言,分頁檔等同於實體記憶體,只是會受頁面的調度而在不同位置出現在不同的實體位置上。 • Windows系統支援一個或多個分頁檔(每個磁碟分割最多一個分頁檔)
Intel x86中的PTE • PTE中各個位元的確切定義:
前面4.1.1節提過,TLB包含了最近使用過的虛擬頁面與實體頁面之間的對應關係,以便快速轉譯虛擬位置,以避免多次的記憶體存取。前面4.1.1節提過,TLB包含了最近使用過的虛擬頁面與實體頁面之間的對應關係,以便快速轉譯虛擬位置,以避免多次的記憶體存取。 • PTE中的G位元若被設定,代表該PTE有效,而不必在TLB中設為無效;若為0則PTE不在有效,因而TLB中也被設為無效。
以上顯式的硬體PTE完全由Intel處理器定義,WRK中也給出對應的C語言定義(base\ntos\mmi\i386\mi386.h)以上顯式的硬體PTE完全由Intel處理器定義,WRK中也給出對應的C語言定義(base\ntos\mmi\i386\mi386.h)