4.4 記憶體分頁

Download Report

Transcript 4.4 記憶體分頁

Team 6
Modern Operating System Kernels
Final Report
975002025
975002018
975002503
975002050
975002525
975002024
975002040
100522007
100522086
100522022
100522061
林彥宇
李韋成
游惇雅
林俊伸
莊欣瑜
沈宗弦
謝宛儀
楊睿豪
陸俊廷
張哲嘉
徐千惠
1
CONTENTS
(page 217 ~ page 256)
Chapter 4 Windows 記憶體管理
4.2 Windows系統記憶體管理
4.2.2 系統位址空間記憶體管理
4.2.3 系統PTE區域的管理
4.3 行程記憶體管理
4.3.1 位址空間的建立和初始化
4.3.2 位址空間切換
4.3.3 行程位址空間的記憶體管理
4.3.4 記憶體區段物件
4.4 記憶體分頁
4.4.1 Intel x86中的PTE
4.4.2 軟體PTE: 無效PTE和原型PTE
2
4.2 WINDOWS系統記憶體管理
4.2.2 系統位址空間記憶體管理
4.2 Windows系統記憶體管理
4.2.1 系統位址空間初始化
4.2.2 系統位址空間記憶體管理
4.2.3 系統PTE區域的管理
975002503 游惇雅
975002025 林彥宇
975002018 李韋成
3
(三) 執行體記憶體集區的管裡演算法
執行體記憶體集區
(非分頁)
系統非分頁
集區
非分頁集區
擴充區域
執行體記憶體集區
(分頁)
系統分頁
集區
系統PTE
集區
4
POOL_DESCRIPTOR

執行體記憶體集區物件是由資料結構POOL_DESCRIPTOR描述
5
全域變數

.
6
初始化

. MiInitializeNonPagedPool
系統非分頁集區初始化
PFN資料庫初始化
InitializePool(NonPagedPool,0)
執行體非分頁集區初始化
MiBuildPagedPool
系統分頁集區初始化
InitializePool(PagedPool,0L)
執行體分頁集區初始化
7
基本演算法


若一次記憶體分配的大小超過
POOL_BUDDY_MAX,則執行體記憶體集區直
接呼叫底層的系統記憶體集區來申請足夠的頁面。
否則,ExAllocatePoolWithTag函式檢查記憶體
集區內部的lookaside list,以期望可找到合適
大小的空閒區塊,若未能找到滿足條件的區塊,
則向系統記憶體集區申請一個新的頁面,把頁面
的一部份傳給客戶,剩下的加入到適當大小的
lookaside list中。
8
管理結構
PoolType
PoolIndex
.
.
ListHeads陣列:
[0]
[1]
[2]
8位元組區塊
[3]
16位元組區塊
8位元組區塊
16位元組區塊
…
[511]
4080位元組區塊
4080位元組區塊
9
頁面內部結構
0
PI
BS PT Tag
PS PI
使用者資料
BS PT Tag
PS PI
使用者資料
BS PT Tag
使用者資料
PS:PreviousSize
PI:PoolIndex
BS:BlockSize
PT:PoolType
10
ExAllocatePoolWithTag (1/2)


.
.
11
ExAllocatePoolWithTag (2/2)

Step 1
◦ 若NumberOfBytes > POOL_BUDDY_MAX則呼
叫MiAllocatePoolPages(),否則就直接使用
lookaside來分配。

Step 2
◦ 確 定 POOL_DESCRIPTOR 物 件 PoolDesc 和 索 引
ListNumber後,使用do迴圈搜尋滿足條件的空閒
區塊。

Step 3
◦ 執行完Step 2仍未找到有效區塊的話,則呼叫
MiAllocatePoolPages函式來向系統記憶體集區申
請一個新的頁面。
12
ExFreePoolWithTag (1/6)


.
Step 1
◦ ExAllocatePoolWithTag 透過
POOL_BUDDY_MAX呼叫
MiAllocatePoolWithTag函式進行配置,相對地,
再釋出空間亦呼叫MiFreePoolWithTag.
13
ExFreePoolWithTag (2/6)

Step 2
◦ 根據參數P,找到相關的POOL_HEADER,置於區
域變數Entry中,並檢查期中的成員資訊,進一步找
到它後面的區塊的POOL_HEADER,檢查後面區塊
的PreviousSize和目前區塊的BlockSize是否相同。

Step 3(小區塊釋放)
◦ 在ExAllocatePoolWithTag 中,配置小區塊即從
Lookaside List中提取適當區塊。相對地,在
ExFreePoolWithTag中,若Lookaside List未達到
預定深度,則將釋出的區塊放入Lookaside List中
※分頁及非分頁集區lookaside list:PPPagedLookasideList & PPNPagedLookasideList
14
ExFreePoolWithTag (3/6)

Step 4-1 (merge)
15
ExFreePoolWithTag (4/6)

Step 4-2 (merge)
16
ExFreePoolWithTag (5/6)

Step 4-3 (merge)
17
ExFreePoolWithTag (6/6)

Step 4-4
(merge)
18
4.2 WINDOWS系統記憶體管理
4.2.3 系統PTE區域的管理
4.2 Windows系統記憶體管理
4.2.1 系統位址空間初始化
4.2.2 系統位址空間記憶體管理
4.2.3 系統PTE區域的管理
19
4.2.3 系統PTE區域的管理
執行體記憶體集區
(非分頁)
系統非分頁
集區
非分頁集區
擴充區域
執行體記憶體集區
(分頁)
系統分頁
集區
系統PTE
集區
20
_MMPTE_LIST

空閒頁面的PTE沒有對應的實體頁面
21
PTE串列 & PTE cluster
PTE cluster(2 PTE)
NextEntry … 0 0
2
… 0 0
xx
… x x
xx
… x x
xx
… x x
PTE cluster(1 PTE)
NextEntry … 1 0
PTE cluster(3 PTE)
NextEntry … 0 0
3
… 0 0
0
… 0 0
22
全域變數

.
23
主要程式碼中之函式

MiInitializeSystemPtes

MiReserveSystemPtes

MiReleaseSystemPtes
24
MiInitializeSystemPtes (1/2)

本函式目的:執行PTE區域的初始化
 Step 1: 在系統非分頁集區的初始化完成後,呼叫本函式執行
PTE區域的初始化
 Step 2: 設定起始PTE和結束PTE的位址
 Step 3: 將這段PTE全部歸零

本函式也初始化單串列
 Step 1: 每個節點是一塊記憶體,稱作Chunk(分為五種大
小:1.2.4.8.16),MilnitializeSystemPtes函式中有個區域陣列
Lists定義了每種chunk的數量
 Step 2: chunk 從系統非分頁集區中分配,加入到
MiSystemPteSListHead定義的單串列中
 Step 3: 利用此單串列來初始化MiSystemPteNBHead
25
MiInitializeSystemPtes (2/2)
i = MM_SYS_PTE_TABLES_MAX;
do{
I -= 1;
do{
Lists[i] -=1;
MiReleaseSystemPtes(PointerPte,
MmSysPteIndex[i],
SystemPteSpace);
PointerPte +=MmSysPteIndex[i];
}while(Lists[i] !=0);
}while(i!=0);
26
MiReserveSystemPtes (1/2)


本函式目的:分配非分頁頁面
含有兩個參數
 NumberOfPtes
 頁面的數量
 SystemPtePoolTyoe
 僅有兩種可能,SystemPteSpace或
NonPagedPoolExpansion,這裡只考慮
SystemPteSpace

根據NumberOfPtes確認應該使用哪種大小的佇列
 如果能從中提取一個節點,直接將之中的起始PTE回
傳給Client.
 如果此種大小的區塊數量小於預定的最小數,則呼叫
MiFeedSysPtePool函式,以獲得更多此種大小的區
塊。
27
MiReserveSystemPtes (2/2)



本函式目的:釋放PTE
Step 1: 本函式的參數指定了要釋放的PTE位置和個數
及類型,而在呼叫此函式之前,指定範圍的PTE必須是
無效的。
Step 2: 將這些PTE全部歸零
 如果帶釋放的數量小於等於16,考慮把這段PTE範圍插入
MiSystemPtesNBHead所指的佇列中,而不直接回收到空閒
的PTE串列。
 若插入不成功或數量超過16則歸還到PTE串列中
 從第一個空閒的PTE開始,即是MmFirstFreeSystemPte陣列的
元素,找到第一個NextEntry欄位超過目前起始PTE的空閒磁簇。
 考慮能否跟他合併成一個更大的磁簇,如果此空閒磁簇恰好緊
貼要釋放的範圍則合併。
 若不能合併則插入一個新的空間磁簇在他的後面。
28
4.3 行程記憶體管理
4.3.1位址空間的建立和初始化
4.3 行程記憶體管理
4.3.1 位址空間的建立和初始化
4.3.2 位址空間切換
4.3.3 行程位址空間的記憶體管理
4.3.4 記憶體區段物件
975002024 沈宗弦
29
4.3.1位址空間的建立和初始化
0x00000000
~
行程位置空間
4GB
0x7 f f f f f f f
0x80000000
~
系統位置空間
0xf f f f f f f f
行程虛擬位置空間
30
4.3.1位址空間的建立和初始化

PspCreateProcess建立行程時,若指定的
Parent行程不為NULL
MmCreateProcessAddressSpace
PspCreateProcess
建立一個新的位址空間
MmInitializeProcessAddressSpace
初始化行程位址空間
31
建立行程位址空間

呼叫MmCreateProcessAddressSpace函式
建立位址空間
(base/ntos/mm/procx86.c 28-362)
BOOLEAN
MmCreateProcessAddressSpace (
IN ULONG MinimumWorkingSetSize,
//建立行程的最小工作集的大小
IN PEPROCESS NewProcess,
//建立行程的行程物件
OUT PULONG_PTR DirectoryTableBase
//指向行程位址空間的分頁目錄位址
)
32
建立行程位址空間 ─ 函式流程
1.
呼叫MiChargeCommitment確保系
統有足夠的分頁業檔空間。
在intel x86,需要4個頁面
33
建立行程位址空間 ─ 函式流程
2.
確認目前實體頁面是否達到
MinimumWorkingSetSize指定的要求
3.
申請一個實體頁面作為分頁目錄頁面
實
體
頁
面
分頁目錄頁面
將分頁框架編號存至
區域變數PageDirectoryIndex中
34
建立行程位址空間 ─ 函式流程
4.
實
體
頁
面
申請一個超空間分頁表頁面
將分頁框架編號存至
區域變數HyperSpaceIndex中
超空間分頁表頁面
什麼是超空間:
這是一個特別的區域,可以用來對應
處理程序工作組清單,也可以暫時地
對應其他的實體分頁,以便進行諸如
零位調整可用清單上的分頁(在零位
清單是空的,但需要使用零位分頁的
時候)、使其他分頁表中的分頁表輸
入失效(例如當某個分頁從待命清單
中移除時),以及關於建立處理程序、
設定新處理程序的位址空間等作業。※1
35
建立行程位址空間 ─ 函式流程
5.
申請一個VAD點陣圖
實
體
頁
面
VAD點陣圖
將分頁框架編號存至
區域變數VadBitMapPage中
VAD點陣圖請參考4.3.3之介紹
36
建立行程位址空間 ─ 函式流程
6.
申請一個實體頁面當作工作集串列
實
體
頁
面
7.
工作集串列
初始化EPROCESS 中的
Vm.MinimumWorkingSetSize ,Workin
gSetPage ,DirectoryTableBase 欄位
37
建立行程位址空間 ─ 函式流程
8.
初始化超空間分頁表頁面
(base/ntos/mm/procx86.c
229-262)
.
.
.
超空間分頁表頁面
一個PTE
.
.
.
系統PTE區
VAD點陣圖
工作集串列
分別填寫完對應的VAD點陣圖與工作集串列的分頁表項目,
完成後釋放此PTE。
38
建立行程位址空間 ─ 函式流程
在PFN資料庫中設置分頁目錄頁面的PTE
位置(虛擬位址0xc0300000)
10. 把新行程加入到系統內部維護行程串列
中
9.
.
.
.
MmProcessLinks
.
.
.
MmProcessList
插入串列中
EPROCESS
39
建立行程位址空間 ─ 函式流程
11. 初始化分頁目錄頁面
(base\ntos\mm\i386\procx86.c第294~353行)
0xc000000
0
.
.
.
分頁目錄頁面
一個PTE
.
.
.
系統PTE(動作
完成後釋放)
之後把4個頁面的負擔紀
錄至MmProcessCommit
中
(全域變數)
0xc400000
0
複製系統空間的PDE
(0x80000000開始的位置範圍)
PDE
超空間分頁表頁面
(內涵VAD及工作集)
行程位置空間
0x80000000
系統位置空間
0xf f f f f f f40f
建立行程位址空間 ─ 函式流程
12. 呼叫MiSessionAddProcess函式把新行
程加入到新行程的父行程所在的工作階
段空間,即MmSessionSpace中。
 MiSessionAddProcess
 更新工作階段空間中的行程計數器,以及將新行程加
入工作階段空間維護的行程串列中。
41
4.3.1位址空間的建立和初始化
MmCreateProcessAddressSpace
PspCreateProcess
建立一個新的位址空間
MmInitializeProcessAddressSpac
初始化行程位址空間
42
4.3.1位址空間的建立和初始化

MmInitializeProcessAddressSpace
函式在以下四種情況會被呼叫
建立新使用者行程時,SectionToMap有效、
ProcessToClone為NULL.
建立新使用者行程時,沒有記憶體區段物件,
類似fork( )操作。
建立新系統行程時, SectionToMap、
ProcessToClone皆為NULL、相關旗標亦為關
閉時。
系統初始化時,Parent為NULL時。
43
初始化行程位址空間

接著呼叫MmInitializeProcessAddressSpace
初始化使用者空間部分(0x0-0x7fffffff)
NTSTSTUS
MmInitializeProcessAddressSpace (
IN PEPROCESS ProcessToInitialize ,
//要初始化的目標行程
IN PEPROCESS ProcessToClone OPTIONAL ,
//新行程的位址空間可從該行程複製獲得
IN PVOID SectionToMap OPTIONAL ,
//提供一記憶體區段物件,鰾是在新行程位址空間中對應此物件
IN OUT PULONG CreateFlags ,
//各種與行程建立相關的旗標
OUT POBJECT_NAME_INFORMATION *AuditName
OPTIONAL ,
//物件名稱資訊指標
);
44
初始化行程位址空間 - 函式流程
1.
2.
3.
判斷是否更新新行程空間中的系統PDE (分頁後半
部分),若需要則呼叫MiUpdateSystemPdes.
呼叫KeAttachProcess, 把目前緒程”暫時”附加
至待初始化的行程物件上。
標明目前正在使用位址空間2.
ProcessToInitialize->Flags = PS_PROCESS_FLAGS_ADDRESS_SPACE2
4.
初始化位址建立鎖及工作集互斥器
ProcessToInitialize->AddressCreationLock
ProcessToInitialize->Vm.WorkingSetMutex
45
初始化行程位址空間 - 函式流程
5.
初始化VAD樹並設置最後修剪時間及工
作集串列
Vm.LastTrimTime
Vm.VmWorkingSetList
6.
7.
8.
初始化新行程分頁目錄和超空間分頁表
的PNF,以及VAD點陣圖和工作集的PNF.
初始化新行程工作集串列。
MiInitializeWorkingSetList
若以3GB啟動方式或64位元系統,則需
另外建立一VAD,來保留共用的使用者
頁面。
46
初始化行程位址空間 - 函式流程
略過
10.根據系統登錄設置及目前系統環境,
來確定是否在新行程中由高向低分配
虛擬位址空間。
9.
47
初始化行程位址空間 - 函式流程
11.建立新行程
EPROCESS
.
.
.
ImageFileName
.
.
.
MmMapViewOfSection 參閱4.3.4
1
(新行程同樣對應) 2
SectionToMap 記憶體區段物件的可執行映像檔
4
(ntdll.dll對應至新行程位址空間) 3
PsMapSystemDll
(把新行程的虛擬位址空間插入工作管理串列)
5 MiAllowWorkingSetExpansion
48
初始化行程位址空間 - 函式流程
12. 行程複製
檢查目前行程每一個VAD,且根據頁面屬性檢
查PTE,並複製到新行程,其複製特性見4.4.4
父行程呼叫MiCloneProcessAddressSpace
複製位址空間後,把新行程虛擬空
間位址插入到工作管理集串列中。
MiAllowWorkingSetExpansion
13. 如果是系統行程則什麼也不做
14. 如果新行程是一個複製的行程或系統行程,
則關閉大頁面建立旗標,結束函式。
(PROCESS_CREATE_FLAGS_LARGE_PAGES)
49
4.3.1位址空間的建立和初始化

經過兩個步驟的建立後,一個行程的空
間位址已經初步建立起來。
MmCreateProcessAddressSpace
PspCreateProcess
建立一個新的位址空間
MmInitializeProcessAddressSpace
初始化行程位址空間
50
4.3 行程記憶體管理
4.3.2 位址空間切換
4.3 行程記憶體管理
4.3.1 位址空間的建立和初始化
4.3.2 位址空間切換
4.3.3 行程位址空間的記憶體管理
4.3.4 記憶體區段物件
975002040 謝宛儀
51
分頁目錄
0x00000000 – 0x7fffffff

前半
每個process私有
完全轉移到新行程的位址空間
0x80000000 – 0xffffffff

後半
每個process共有,但分頁目錄頁面為獨立的。
新位址空間中的PDE項目指向全域的分頁表
52
系統位址空間的記憶體配置結構
0x80000000 
MmPfnDatabase
核心、HAL等系統模組的
映象區
分頁表是否 頁面是否
已分配
已分配
√
√
√
√
MmNonPagedPoolStart
非分頁集區
√
√
MiSystemCacheStartExtra
系統快取額外區
MiSystemCacheSizeExtra(個頁面)
√
╳
系統PTE額外區
√
╳
工作階段管理員、
MiSystemViewStart 
系統檢視
╳
╳
Windows子系統
MmSessionBase 
工作階段空間
╳
╳
0xc0000000
分頁表
√
√
0xc0400000 
超空間和行程工作集
√
╳
可能在不同行程的分頁目錄中
MmSystemCacheWorkingSetList(0xc0c00000)
系統快取結構 有不同的檢視
√
╳
MmPagedCacheStart(0xc1000000) 
系統快取
√
╳
MmPagedPoolStart 
分頁集區
╳
╳
MmNonPagedPoolExpansionStart 
系統PTE區域
√
╳
非分頁集區擴充區
√
╳
0xffbe0000
當機轉存區
√
╳
保留區
√
╳
53
0xffffffff
PFN 資料庫
4.3.2 位址空間切換

新行程有可能指向錯誤的分頁集區,產生分
頁錯誤。
利用延遲計算(lazy evaluation)來保持分頁集
區分頁表對應的一致性
◎MmSystemPagePtes記錄了分頁集區的分頁表對應

在行程切換前後,新老行程的工作集串列和
VAD點陣圖所對應的PDE指向各自的超空間
分頁表頁面。
◎MmWorkingSetList為目前行程的工作集串列
54
4.3.2 位址空間切換

Windows行程切換實作
 只需切換分頁目錄頁面,即CR3暫存器。
 無須對分頁目錄中的PDE做任何調整或一
致性維護。
 系統空間中除了超空間和工作階段空間部
分以外,在新老行程中保持一致。
55
4.3 行程記憶體管理
4.3.3 行程位址空間的記憶體管理
4.3 行程記憶體管理
4.3.1 位址空間的建立和初始化
4.3.2 位址空間切換
4.3.3 行程位址空間的記憶體管理
4.3.4 記憶體區段物件
975002050 林俊伸
56
4.3.3 行程位址空間的記憶體管理

使用者模式只能使用 0x0 – 7fffffff的記憶體
位址
保留一段記憶體,
但不真正使用。

實際使用記憶體
使用者程式必須經過以下兩步驟才能使用
◦ (1)Reserve
(2)Commit
實際可提交的量 = 全部實體記憶體 + 分頁檔 – 系統使用記憶體
57
4.3.3 行程位址空間的記憶體管理
VirtualAlloc
空閒
VirtualAllocEx
保留
VirtualFreeEx
Virtuallock
提交
VirtualFree
VirtualUnlock
58
4.3.3 行程位址空間的記憶體管理
上
層
VirtualFree
VirtualFree
Ex
VirtualAlloc
VirtualAllocEx
實
作
NtAllocateVirtualMemory
NtFreeVirtualMemory
下
層
59
4.3.3 行程位址空間的記憶體管理
Window的行程位址透過VAD管理
 VAD初始化

MmInitializeProcessAd
dressSpace
EPROCESS物件
VadRoot欄位
VADRoot類型
MM_AVL_TABLE
typedef struct _MM_AVL_TABLE {
MMADDRESS_NODE
BalancedRoot;
ULONG_PTR DepthOfTree: 5;
ULONG_PRT Unused: 3;
ULONG_PRT
NumberGenericTableElements: 24;
VAD
PVOID NodeHint; 樹根
PVOID NodeFreeHint;
} MM_AVL_TABLE,
*PMM_AVL_TABLE;
60
VAD樹中節點型別 (1/2)
typedef struct _MM_MMADDRESS_NODE {
維護AVL
union {
樹本身
LONG_PTR Balance : 2;
struct _MMVAD * parent;
}
struct _MMVAD * LeftChild;
struct _MMVAD * RightChild;
ULONG_PTR StartingVpn;
ULONG_PTR EndingVpn;
} MMADDRESS_NODE,
*PMMADDRESS_NODE;
61
VAD樹中節點型別 (2/2)
typedefstruct
struct _MMVAD {
typedef
union {
_MM_MMADDRESS_NODE
{
LONG_PTR
Balance : 2;
union
{
struct
_MMVAD
* parent;
LONG_PTR
Balance
: 2;
} struct _MMVAD * parent;
struct
_MMVAD * LeftChild;
}
struct _MMVAD * RightChild;
LeftChild;
ULONG_PTR
StartingVpn;
struct _MMVAD
* RightChild;
ULONG_PTR EndingVpn;
StartingVpn;
} MMADDRESS_NODE,
ULONG_PTR EndingVpn;
*PMMADDRESS_NODE;
} MMADDRESS_NODE,
…
*PMMADDRESS_NODE;
範圍
樹真正結點類型為
MMVAD
62
VadRoot.BalancedRoot.RightChild
VAD樹
[10, 10]
左子點
[20, 20]
[130,134]
[270, 2a3]
[300,305]
Root
[240,24f]
[2b0, 2f0]
[320, 322]
右子點
[67000, 6700e]
[77e40, 77f41]
[7ffb0, 7ffd3]
[410,50f]
[77c50,77cee]
[7c800, 7c8bf]
[7ffdd, 7ffde]
一個實際行程的VAD樹
提交or保留
[30, 13f]
[140,23f]
[250,265]
[310,31f]
[330,33f]
[510,56f]
[77f50,77feb]
[7f6f0,7f7ef]
[7ffdb,7ffdb]
[7ffdc,7ffdc]
[7ffde,7ffde]
63
TABLE SEARCH_RESULT
MiFindNodeOrparent )
IN PMM_AVL_TABLE Table,
IN ULONG_PTR StartingVpn,
OUT PMMADDRESS_NODe
*NodeOrParent
);
AVL 實作: Base\ntos\mm\addrsup.c

MiFindNodeOrParent ()

MiInsertNode()

MiRemoveNode()
VOID
FASTCALL
MiInsertNode (
IN PMMADDRESS_NODE
NodeToInsert,
IN PMM_AVL_TABLE Table
);
VOID
FASTCALL
MiInsertNode (
IN PMMADDRESS_NODE
NodeDelete,
IN PMM_AVL_TABLE Table
);
64
MiFindNodeOrParent ()
TABLE SEARCH_RESULT
MiFindNodeOrparent )
尋找這點父節
點orAVL節點
IN PMM_AVL_TABLE Table,
IN ULONG_PTR StartingVpn,
OUT PMMADDRESS_NODe
*NodeOrParent
);
65
MiInsertNode() & MiRemoveNode()
VOID
FASTCALL
MiInsertNode (
IN PMMADDRESS_NODE
NodeToInsert,
IN PMM_AVL_TABLE Table
);
VOID
FASTCALL
MiInsertNode (
IN PMMADDRESS_NODE
NodeDelete,
IN PMM_AVL_TABLE Table
);
66
VAD點陣圖
找尋位置
是否保留
或提交
找尋連續
的空閒位
址範圍
位元表示64k記憶體是否出現在VAD樹中
VAD樹
找尋連續空
閒位元
VAD點
陣圖
67
VAD點陣圖相關函式
MiInsertVadCharges()

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);

MiReturnPageTablePateCommitment()

MiFindEmptyAddressRange()
VadBitMap.SizeOfBitMap =
MiLastMadBit + 1;
BadBitMap.Buffer =
VAD_BITMAP_SPACE;
RtlSetBits (&VadBitMap,
StartBit, EndBit – StartBit +
1);
68
4.3 行程記憶體管理
4.3.4 記憶體區段物件 (1/2)
4.3 行程記憶體管理
4.3.1 位址空間的建立和初始化
4.3.2 位址空間切換
4.3.3 行程位址空間的記憶體管理
4.3.4 記憶體區段物件
975002040 謝宛儀
69
4.3.4 記憶體區段物件



是windows平台上兩個或多個行程之間共用記
憶體的一種常用方法
實體儲存資源
直接以操作記憶體的方式存取檔案
建立行程
位址空間
可
執
行
檔
映
像
記憶體區段物件
70
物件主體定義
(base\ntos\mm\mi.h)
// 記憶體區的VAD節點
// 指向一個區段物件
// 記憶體區的大小
// 包含記憶體區的一組旗標
// 指定記憶體區中頁面的保護屬性
71
4.3.4 記憶體區段物件

分兩種
 分頁檔支撐的記憶體區(page file backed
section), 也稱為檔案對應物件(file
mapping object).
 檔案支撐的記憶體區段(file backed
section)

記憶體區段的建立
 由MmCreateSection函式來完成的
(base\ntos\mm\creasect.c 402-1611行)
72
記憶體區段的建立 (1/8)

(base\ntos\mm\creasect.c)
73
記憶體區段的建立 (2/8)


(base\ntos\mm\creasect.c)
分頁檔支撐的記憶體區(page file backed
section)也稱為檔案對應物件(file mapping
object).
指定記憶體區的大小
空
74
記憶體區段的建立 (3/8)


(base\ntos\mm\creasect.c)
檔案支撐的記憶體區段(file backed section)
指定了記憶體區
最大可被擴充或對應的大小
非空
75
記憶體區段的建立 (4/8)

(base\ntos\mm\creasect.c)
指定記憶體區中
每個頁面的保護旗標
76
記憶體區段的建立 (5/8)

(base\ntos\mm\creasect.c)
指定記憶體區段物件中
:
記憶體區段的分配方式
SEC_BASED
SEC_RESERVE
SEC_COMMIT SEC_IMAGE
SEC_FILE
SEC_LARGE_PAGES
指定記憶體區中
每個頁面的保護旗標
77
記憶體區段的建立 (6/8)

(base\ntos\mm\creasect.c)
指定記憶體區段物件中
記憶體區段的分配方式
SEC_BASED
SEC_RESERVE
SEC_COMMIT SEC_IMAGE
SEC_FILE
指定了物件管理員所要的資訊,
SEC_LARGE_PAGES
包括物件名、安全描述項等等。
78
記憶體區段的建立 (7/8)


(base\ntos\mm\creasect.c)
記憶體區段物件未命名以致不能共用
記憶體區的頁面
為私有頁面
指定了物件管理員所要的資訊,
包括物件名、安全描述項等等。
79
記憶體區段的建立 (8/8)

(base\ntos\mm\creasect.c)
指定存取方式:
EXECUTE、READ、
WRITE
80
MmCreateSection函式的程式碼邏輯
②
①
③
(1/3)
填充
區段
SEGMENT
ControlAre
a
MmCreateSection
分頁檔支撐的記憶體集區
控制區
檔案物件
MiCreatePagingFileMap
CONTROL_AREA
FILE_OBJECT
SectionObjectPoin
Segment
映像檔記憶體集區
ter
FilePointer
MiCreateImageFileMap
SUBSECTION
有對應的
子記憶體區段
檔案物件
SUBSECTION
資料檔案記憶體集區
子記憶體區段
有任一個為非空
MiCreateDataFileMap
……
81
MmCreateSection函式的程式碼邏輯
②
①
MmCreateSection
(2/3)
分頁檔支撐的記憶體集區
MiCreatePagingFileMap
映像檔記憶體集區
MiCreateImageFileMap
資料檔案記憶體集區
空
MiCreateDataFileMap
有對應的
檔案物件
82
MmCreateSection函式的程式碼邏輯

(3/3)
(base\ntos\mm\creasect.c)
83
記憶體區段物件與其他物件的關聯結構 (1/3)
記憶體區段
物件
Segment
區段
SEGMENT
ControlArea
控制區
CONTROL_AREA
Segment
FilePointer
SUBSECTION
子記憶體區段
SUBSECTION
子記憶體區段
虛擬位址描述項
MMVAD
ControlArea
……
記憶體區段物件指標
SECTION_OBJECT_POITERS
DataSectionObject
ImageSectionObject
檔案物件
FILE_OBJECT
SectionObjectPoin
ter
84
記憶體區段物件與其他物件的關聯結構 (2/3)
區段物件本身是在分頁集區中分配的,並且有一指
標指向一個控制區物件,用於描述此區段內頁面對
應的原型PTE陣列等資訊。
 控制區物件(CONTROL_AREA結構)是在非分頁
集區分配的,它有一個指標指向區段物件,維護
反映了與之關聯的記憶體區段物件被對應了多少次
I/O操作所必要的資訊。

控制區
CONTROL_AREA
區段
SEGMENT
ControlArea
Segment
FilePointer
SUBSECTION
子記憶體區段
SUBSECTION
子記憶體區段
……
檔案物件
FILE_OBJECT
SectionObjectPoint
er
85
記憶體區段物件與其他物件的關聯結構 (3/3)

檔案物件是Windows I/O和儲存系統中的一
個核心物件,也是記憶體管理子系統與I/O子
系統打交道的重要途徑。
控制區
CONTROL_AREA
Segment
FilePointer
SUBSECTION
子記憶體區段
SUBSECTION
子記憶體區段
……
檔案物件
FILE_OBJECT
SectionObjectPointer
記憶體區段物件指標
SECTION_OBJECT_POINTERS
DataSectionObject
ImageSectionObject
86
4.3 行程記憶體管理
4.3.4 記憶體區段物件 (2/2)
4.3 行程記憶體管理
4.3.1 位址空間的建立和初始化
4.3.2 位址空間切換
4.3.3 行程位址空間的記憶體管理
4.3.4 記憶體區段物件
975002525 莊欣瑜
87
建立區段(SEGMENT)物件 (1/2)
NtCreateSection
MmCreateSection
分頁檔支撐的記憶體集區
MiCreatePagingFileMap
映像檔記憶體集區
MiCreateImageFileMap
資料檔案記憶體集區
MiCreateDataFileMap
有對應的
檔案物件
88
建立區段(SEGMENT)物件 (2/2)
89
建立記憶體區段物件
NtCreateSection
MmCreateSection
分頁檔支撐的記憶體集區
MiCreatePagingFileMap
映像檔記憶體集區
MiCreateImageFileMap
資料檔案記憶體集區
MiCreateDataFileMap
90
分頁檔支撐的記憶體區段物件 (1/4)

MiCreatePagingFileMap
確定所需
memory大小
ExAllocatePoolWithTag
申請記憶體
初始化區段物件
中的成員
申請CONTROL_AREA
物件
初始化
CONTROL_AREA和
子記憶體區的成員
91
分頁檔支撐的記憶體區段物件 (2/4)
NtMapViewOfSection
MmMapViewOfSection
分頁檔支撐的記憶體集區
MiMapViewOfDataSection
映像檔記憶體集區
MiMapViewOfImageSection
資料檔案記憶體集區
MiMapViewOfDataSection
實體記憶體區
MiMapViewOfPhysicalSection
92
分頁檔支撐的記憶體區段物件 (3/4)
NtMapViewOfSection
MmMapViewOfSection
分頁檔支撐的記憶體集區
MiMapViewOfDataSection
映像檔記憶體集區
MiMapViewOfImageSection
資料檔案記憶體集區
MiMapViewOfDataSection
實體記憶體區
MiMapViewOfPhysicalSection
93
分頁檔支撐的記憶體區段物件 (4/4)

MiMapViewOfDataSection
呼叫
MiFindEmptyAddressRangeDown
或MiFindEmptyAddressRange確定
行程的位址空間範圍
範圍內的PTE
設置成區段物
件的
SegmentPte
Template值
把VAD物件
插入目標行
程的VAD樹
中
申請VAD物
件、初始化
讓VAD物件的
ControlArea指向記憶體
區的控制區物件
94
可執行映像檔的記憶體區段物件
NtCreateSection
MmCreateSection
(1/5)
分頁檔支撐的記憶體集區
MiCreatePagingFileMap
映像檔記憶體集區
MiCreateImageFileMap
資料檔案記憶體集區
MiCreateDataFileMap
95
可執行映像檔的記憶體區段物件

(2/5)
MiCreateImageFileMap
從映像檔讀取標頭資訊
利用標頭中的資訊填充
控制區和區段物件中各
個成員
在非分頁集區建立一個
控制區物件; 在分頁集
區建立一區段物件
Note:
• 子記憶體區段物件的數量與映
像檔中區域(SECTION)數量相
等
• 子記憶體區有自己的保護屬性、
原型PTE、在磁碟上的位置
96
可執行映像檔的記憶體區段物件

(3/5)
MiInsertImageSectionObject
記憶體區段
物件
Segment
區段
SEGMENT
ControlArea
控制區
CONTROL_AREA
Segment
FilePointer
SUBSECTION
子記憶體區段
SUBSECTION
子記憶體區段
虛擬位址描述項
MMVAD
ControlArea
……
記憶體區段物件指標
SECTION_OBJECT_POITERS
DataSectionObject
ImageSectionObject
檔案物件
FILE_OBJECT
SectionObjectPoin
ter
97
可執行映像檔的記憶體區段物件
NtMapViewOfSection
(4/5)
分頁檔支撐的記憶體集區
MiMapViewOfDataSection
映像檔記憶體集區
MiMapViewOfImageSection
MmMapViewOfSection
資料檔案記憶體集區
MiMapViewOfDataSection
實體記憶體區
MiMapViewOfPhysicalSection
98
可執行映像檔的記憶體區段物件

(5/5)
MiMapViewOfImageSection
確定目標虛
建立VAD節
擬位址
點物件
把VAD物件
插入到行程
的VAD樹中
由參數CapturedBase指定
由記憶體區段物件的區段物件的
BasedAddress成員決定
呼叫MiFindEmptyAddressRangeDown
或MiFineEmptyAddressRange
99
資料檔案的記憶體區段物件 (1/4)
NtCreateSection
MmCreateSection
分頁檔支撐的記憶體集區
MiCreatePagingFileMap
映像檔記憶體集區
MiCreateImageFileMap
資料檔案記憶體集區
MiCreateDataFileMap
10
0
資料檔案的記憶體區段物件 (2/4)
建立一個控制區物件,存在在File Object的
SectionObjectPointer的
DataSectionObject成員中
確定記憶體區大小
呼叫
MiCreateDataFileMap
函式
在分頁集區中申請一區段物件
控制區的子記憶體區從一個擴充到多個
把原檔案打散成大小為
MmallocationFragment的一組
chunk
MiCreateDataFileMap初始
化控制區物件和區段物件
10
1
資料檔案的記憶體區段物件 (3/4)
NtMapViewOfSection
MmMapViewOfSection
分頁檔支撐的記憶體集區
MiMapViewOfDataSection
映像檔記憶體集區
MiMapViewOfImageSection
資料檔案記憶體集區
MiMapViewOfDataSection
實體記憶體區
MiMapViewOfPhysicalSection
10
2
資料檔案的記憶體區段物件 (4/4)

MiMapViewOfDataSection
確定目標虛
建立VAD節
擬位址
點物件
把VAD物件
插入到行程
的VAD樹中
由參數CapturedBase指定
由記憶體區段物件的區段物件的
BasedAddress成員決定
呼叫MiFindEmptyAddressRangeDown或
MiFineEmptyAddressRange
10
3
特殊記憶體區段物件 (1/4)

\\Device\\PhysicalMemory
 系統初始化階段由MiSectionInitialization函
式直接建立
 沒有呼叫MmCreateSection函式
 可用於直接把實體記憶體對應到行程位址空
間中
10
4
特殊記憶體區段物件 (2/4)

\\Device\\PhysicalMemory
NtMapViewOfSection
分頁檔支撐的記憶體集區
MiMapViewOfDataSection
映像檔記憶體集區
MiMapViewOfImageSection
MmMapViewOfSection
資料檔案記憶體集區
MiMapViewOfDataSection
實體記憶體區
MiMapViewOfPhysicalSection
10
5
特殊記憶體區段物件 (3/4)

\\Device\\PhysicalMemory
以SectionOffset和
CapturedViewSize
兩個參數決定對應範
圍
設置虛擬位
址範圍中的
維護行程
分頁目錄項
內部的資
目和分頁表
料結構
項目
10
6
特殊記憶體區段物件 (4/4)


\\Device\\PhysicalMemory
解除對應
呼叫NtUnmapViewOfSection系統服務
MiUnmapViewOfSection函式
根據給定的基底位址找到VAD節點
從VAD樹中移除節點
呼叫MiRemoveMappedView函式
來解除對應
10
7
4.4 記憶體分頁
100522007 楊睿豪
100522086 陸俊廷
10
8
Paging
分頁錯誤
Kernel Trap
Handler
PTE
Memory Manager
的Page Fault
Handler(MmAcces
allocate sFault)解決
Valid Bit= 0
PTE
Valid Bit = 1
虛擬位址
轉譯成實
體位址
But實體記
憶體有限,
當Process
變多時會有
耗光的問題
一般來說,只要
這個Page Fault
合理(EX: 該頁面
已被Swap Out到
外部記憶體),則
Page Fault
Handler會分配實
體頁面,
並設置好PTE。
現今的作業系統大多都提供
Paging功能,將某些頁面
Swap Out到磁碟中儲存,以
空出實體頁面來。
(Windows系統支援一到多個
Page Files,來存放被交換頁面
的內容。)
10
9
4.4 記憶體分頁
4.4.1 INTEL X86中的PTE
4.4 記憶體分頁
4.4.1 Intel x86中的PTE
4.4.2 軟體PTE: 無效PTE和原型PTE
4.4.3 分頁錯誤處理
4.4.4 Windows的寫時複製
11
0
Intel x86的硬體PTE
寫
保留
全域
大頁面
髒
存取過
禁止存取
直接寫
模式
寫
有效
PTE(分頁目錄項目)
PDE(分頁表項目)
PDE與PTE使用相同格式,
唯一區別只在,第七位
元L位元僅對PDE有效
分頁框架編號
(20位元)
31
U
R
R
12 11 10 9
僅適用於多
處理器系統
G
8
L
7
僅適用
於PDE
D
6
A
Cd
Wt
U/S
W
5
4
3
2
1
V
0
必須為1
111
PTE 狀態位元含義
位元
名稱
說明
V
有效
此虛擬頁面是否對應到一個實體頁面
W
寫
在單一處理器上指明可讀寫或唯讀;在多處理器上指明是否可寫。
U/S 模式位元 核心模式程式碼才可存取(0)或使用者模式程式碼可存取(1)
W  1: 可寫 (實做COPY-ON-WRITE)。0: 唯讀。
Wt
直接寫
Write-through / write-back 策略
U/S  1: 只有核心模式程式碼可存取,0: 使用者/核心模式程式碼皆可存取。
Cd
禁止快取 該頁面禁止快取
A
存取過
頁面已經被存取過 (讀取或寫入)
D
髒
頁面已經被寫過
A 當頁面第一次被存取(讀/寫),A位元一定被設定。
L
大頁面
這是一個大頁面PDE,該位元對於PTE無用。
D 當頁面第一次被寫,D位元會被設定。
G
全域
此PTE適用於所有的行程
U
G  TLB可幫助快速轉譯虛擬位址。1:
PTE仍有效,TLB設為有效;0: 說明可讀寫或唯讀。
PTE無效,TLB
寫
由軟體控制的位元,此位元僅適用於多處理器系統,
設為無效。
U 用於多處理系統,說明一個頁面已經被另一個處理器寫過。
112
硬體 PTE 定義

Base\ntos\mm\i386\mi386.h
11
3
4.4 記憶體分頁
4.4.2 軟體PTE: 無效PTE和原型PTE
4.4 記憶體分頁
4.4.1 Intel x86中的PTE
4.4.2 軟體PTE: 無效PTE和原型PTE
4.4.3 分頁錯誤處理
4.4.4 Windows的寫時複製
11
4
無效PTE和原型PTE
分頁錯誤
PTE
Valid bit = 0
Kernel Trap
Handler
Memory Manager
的Page Fault
Handler(MmAcces
分派 sFault)解決
所以,PTE中的
其他位元是由作
業系統解譯的。
正是因為有了這一層的靈活性,Windows可以在這樣
的PTE中承載一些資訊,以便實作頁面的管理功能。
11
5
導致 page fault 的原因
補充資料
Fault理由
結果
嘗試讀寫一個不在記憶體內,但是在磁碟上的分
頁檔或記憶體映射檔上的page
配置實體page,從磁碟載入對應的
page並放到相應的working set內
嘗試讀寫一個位於待命或以修改清單內的page
將page交給對應的process、session
或系統working set
嘗試讀寫一個為committed的page
違反操作限制
從user mode中嘗試讀寫只允許kernel
mode使用的page
違反操作限制
嘗試寫入唯讀page
違反操作限制
嘗試讀寫demand-zero page
將填滿0的page加入對應的working
set
寫入copy-on-write page
建立process私有的page複本,換掉
process或系統working set原本的
page
寫入有效但尚未寫回後援儲存裝置的page
設定PTE的Dirty bit
嘗試執行標記為防止執行的page
違反操作限制
嘗試寫入guard page
違反guardpage操作限制
116
4.4 記憶體分頁
4.4.2 軟體PTE: 無效PTE和原型PTE
11
7
無效PTE
Invalid PTE

在Windows中,無效的PTE共有四種情況
1.
2.
3.
4.
In Page File (位於分頁檔中)
Demand Zero Page (要求零頁面)
Page Transition (頁面正在轉移)
Unknown (未知)
11
8
無效PTE
Case1: In Page File
31
12 11 10 9
Page File Offset
0
Transition Bit
Page File
0
(位於分頁檔)
5 4
Protection
Prototype Bit
1
Page File Number
0
0
Valid Bit
所要求的Page位於Page File當中。
這會引發載入Page File的動作
119
無效PTE
Case2: Demand Zero
Page File Offset
31
12 11 10 9
0
0
Transition Bit
零頁面
0
5 4
Protection
Prototype Bit
1
0
0
0
Valid Bit
頁面尚未分配,待下次存取時請
求一個zero page.
120
無效PTE
Case3: Page Transition
31
12 11 10 9
5 4
Page Frame Number 1 0 Protection Cd
Transition Bit
page
Prototype Bit
3
Wt
2
U/S
1
W
0
0
Valid Bit
頁面還在記憶體中,但在換出的過程中,
位於系統的某個實體頁面串列中。
121
無效PTE
Case4: Unknown
為一個全零的PTE
31
12 11 10 9
0
0
Transition Bit
0
5 4
0
Prototype Bit
必須檢查VAD
1
0
0
0
Valid Bit
PTE是0或是Page Table還不存在。這兩
種情況都代表需要去檢查VADs來判斷虛
擬位址是否已經committed。如果是的話,
就建立Page Table來代表所committed的
位址空間。
122
無效PTE
無效 PTE 定義
12
3
4.4 記憶體分頁
4.4.2 軟體PTE: 無效PTE和原型PTE
12
4
原型PTE
原型PTE

如果Page可以在兩個Processes之間共享
的話,Memory Manager會使用名為
Prototype Page Table Entries (PTEs)的
結構來映射這些可能被共享的Pages。
12
5
原型PTE
原型PTE (cont.)
 對於以Page
File後援的sections而言,會在
最初建立Section Objects的時候建立
Prototype PTEs陣列。
 對於檔案映射而言,會在映射每個view的時
候視需要建立陣列。這些Prototype PTEs屬
於segment結構的一部分。
12
6
原型PTE
原型PTE: Shared Page
memory manager會
使 用 Prototype PTE
的結構來映射這些可
能會被共享的pages
若Page可共享
Shared
Pages
process
first
process
page table
PTE
原型PTE
process
page
(映射到 section
object view)
memory manager
當process首次取用一個映射到
section object view 的 page
時,memory manager會使用原
型PTE的資訊填寫真正用來轉譯
位址的PTE
原型PTE
Info
memory manager
12
7
原型PTE
原型PTE: Shared Page失效
page
(共享)
生效
失效
process
page
table
PTE
實體page
(有資料)
特殊PTE
原型PTE
128
原型PTE
原型 PTE 定義
12
9
原型PTE
當Shared Pages失效時,硬體PTE直接
指向原型PTE。
31
11 10
Prototype PTE Address
1
(7-27Bits)
9
0
8
7
1
Prototype PTE (0-6Bits)
Prototype Bit
0
0
Valid Bit
指向原型 PTE的無效PTE
130
硬體PTE指向原型PTE
13
1
原型PTE
CASE 1 : Active
寫
保留
全域
大頁面
髒
存取過
禁止存取
直接寫
模式
寫
有效
分頁框架編號
(20位元)
31
12
U
R
R
11 10 9
G
8
L
7
D
6
A
Cd
Wt
U/S
W
5
4
3
2
1
V
0
Page位於實體記憶體內,因為先前有Process存取過它
132
原型PTE
CASE 2 : Page File
31
12 11 10 9
Page File Offset
0
Transition Bit
0
5
Protection
4
1
Page File Number
Prototype Bit
0
0
Valid Bit
Page位於Page File內
133
原型PTE
CASE 3: Mapped File
31
12 11 10 9
Mapping File
Offset
0
Transition Bit
0
5
Protection
4
1
Page File Number
Prototype Bit
0
0
Valid Bit
第13~21位元為Mapping file中的偏移量
Page位於映射檔內
134
原型PTE
CASE 4: Demand Zero
31
12 11 10 9
0
0
Transition Bit
0
5
4
Protection
Prototype Bit
1
0
0
0
Valid Bit
頁面尚未分配,待下次存取時請求一個zero page
135
原型PTE
CASE 5: Transition
31
12 11 10 9
Page Frame Number
1
Transition Bit
0
5 4
Protection
Prototype Bit
Cd
3
2
1
0
Wt
U/S
W
0
Valid Bit
頁面在memory中,已被轉移到某實體頁面串列中,可透過
查詢PFN獲知確切狀況。
136
原型PTE
CASE 6: Modified No-Write
31
12 11 10 9
Page Frame Number
1
Transition Bit
0
5 4
Protection
Prototype Bit
Cd
3
2
1
0
Wt
U/S
W
0
Valid Bit
頁面在實體記憶體中,已被修改過,但修改頁面寫出器不會
將其寫回磁碟中。
137
原型PTE
C union - MMPTE 定義
13
8
原型PTE
原型PTE Example
行程A分頁目錄
PDEA_1
行程A分頁表
實體記憶體
PTE_1
PTE_2
行程B分頁目錄
PDEB_1
記憶體集區的區段物件
區段物件結構
原型PTE
行程B分頁表
頁面
頁面P1
P1
頁面P2
P1(有效)
P2( 有效
無效 )
分頁檔
PTE_1
PTE_2
完成
頁面
P2
139
Reference
1)
什麼是超空間
http://support.microsoft.com/kb/294418/zh-tw
2)
VirtualFree
http://msdn.microsoft.com/enus/library/windows/desktop/aa366892(v=vs.85).aspx
3)
VirtualFreeEx
http://msdn.microsoft.com/enus/library/windows/desktop/aa366894(v=vs.85).aspx
4)
VirtualAlloc function
http://msdn.microsoft.com/enus/library/windows/desktop/aa366887(v=vs.85).aspx
5)
作者:Mark E. Russinovich and David A. Solomon with Alex lonescu
譯者:鄧瑋敦, “深入Windows核心:Windows Internals(第五版)”
出版社:博碩
14
0
Q&A
141
Q:
WINDOWS在PROCESS ADDRESS
SPACE MANAGEMENT當中,是用
VAD來管理的。那我們要如何在VAD
樹當中尋找連續的ADDRESS SPACE?
14
2
A:
由於VAD BITMAP中的每一個位元是
代表著64KB記憶體是否出現在VAD
TREE中。因此,想要找到
CONTINUOUS FREE ADDRESSES,
可以透過在VAD BITMAP中搜尋連續
的空閒旗標位元即可。
14
3
The End
Thank you for your listening!
14
4