Windows核心情景分析-記憶體管理1
簡述
現代意義上的作業系統,就必須提供對核心的保護、對不同使用者程式之間的隔離,並允許軟體的裝入位置浮動。提供這些功能,需要由單獨的記憶體管理來支援。
上圖ALU將程式中的地址計算轉換為虛擬地址(線性地址),然後通過MMU將虛擬地址轉換為實際的實體地址。這些過程對於應用程式而言是透明的。虛擬地址通過段選擇子內容結合偏移地址得到,虛擬地址通過MMU對映機制,通常以頁為單位進行對映,建立對應關係,最終訪問實體記憶體頁面。
由於記憶體管理涉及的細節很多,這裡只記錄重要的和書中需要細思理解的部分,具體內容還是間書籍,結合著看,應該就能理解。
核心對使用者空間的管理
每個程序都有自己的使用者空間,其程序控制塊EPROCESS中有個指標VadRoot,指向代表使用者空間的資料結構。定義為:
每個程序都存在一個這樣的資料結構。其中 MemoryAreaRoot所指向一顆二叉樹,MEMORY_AREA結構為:
typedef struct _MEMORY_AREA { PVOID StartingAddress; PVOID EndingAddress; struct _MEMORY_AREA *Parent; struct _MEMORY_AREA *LeftChild; struct _MEMORY_AREA *RightChild; ULONG Type; ULONG Protect; ULONG Flags; BOOLEAN DeleteInProgress; ULONG PageOpCount; union { struct { ROS_SECTION_OBJECT* Section; ULONG ViewOffset; PMM_SECTION_SEGMENT Segment; BOOLEAN WriteCopyView; LIST_ENTRY RegionListHead; } SectionData; struct { LIST_ENTRY RegionListHead; } VirtualMemoryData; } Data; } MEMORY_AREA, *PMEMORY_AREA;
當需要從一個空間中分配一個地址區間時,可以通過MMCreateMemoryArea()建立一個MEMERY_AREA節點,且插入其二叉樹中。上面結構成分Data是個union,如果這個區間代表一個Section,即檔案對映區或共享記憶體區,Data就是一個SectionData資料,如果代表普通已分配記憶體,則為VirtualMemoryData資料結構,其RegionListHead用來維持一個區塊佇列,一個已分配的區間只是一個地址連續的範圍,不一定具有同類型保護模式,而區塊則不但地址連續,而且具有相同型別保護模式,一個區間可能具有多個區塊。區塊結構定義如下:
typedef struct _MM_REGION { ULONG Type; ULONG Protect; ULONG Length; LIST_ENTRY RegionListEntry; } MM_REGION, *PMM_REGION;
區塊是由一組虛存頁面構成,具有相同保護模式。所以對於記憶體管理有這樣層次:空間,區間,區塊,頁面。
巨集操作#define CONTAINING_RECORD(address,type,field) ((type FAR*)(\
(PCHAR)(address) - (PCHAR)(&((type *)0)->field)))
巨集展開為:
((MM_REGION FAR *)((PCHAR)(current_entry) - (PCHAR)(&((MM_REGION *)0)->RegionListEntry)))
在current_entry的基礎上減去RegionListEntry在MM_REGION結構內部的位移。