页面交换
首先是PTE的类型
X86硬件PTE
V位如果为1,转译正常进行,V位如果为0 硬件将发生页面错误 交由系统处理
typedef struct _MMPTE_HARDWARE {
ULONG Valid : 1;
#if defined(NT_UP)
ULONG Write : 1; // UP version
#else
ULONG Writable : 1; // changed for MP version
#endif
ULONG Owner : 1;
ULONG WriteThrough : 1;
ULONG CacheDisable : 1;
ULONG Accessed : 1;
ULONG Dirty : 1;
ULONG LargePage : 1;
ULONG Global : 1;
ULONG CopyOnWrite : 1; // software field
ULONG Prototype : 1; // software field
#if defined(NT_UP)
ULONG reserved : 1; // software field
#else
ULONG Write : 1; // software field - MP change
#endif
ULONG PageFrameNumber : 20;
} MMPTE_HARDWARE, *PMMPTE_HARDWARE;
以上是PTE有效时的定义 也就是CPU直接寻到物理地址时的定义
1.在辅存中
typedef struct _MMPTE_SOFTWARE {
ULONG Valid : 1;
ULONG PageFileLow : 4; 用于索引在哪个页面文件中,页面文件的结构MMPAGING_FILE 存储在一个MmPagingFile的数组中 一共可以支持16个页面文件
ULONG Protection : 5;
ULONG Prototype : 1;
ULONG Transition : 1;
ULONG PageFileHigh : 20; 在页面文件中的偏移
} MMPTE_SOFTWARE;
typedef struct _MMPTE_TRANSITION {
ULONG Valid : 1;
ULONG Write : 1;
ULONG Owner : 1;
ULONG WriteThrough : 1;
ULONG CacheDisable : 1;
ULONG Protection : 5;
ULONG Prototype : 1;
ULONG Transition : 1;
ULONG PageFrameNumber : 20;
} MMPTE_TRANSITION;
typedef struct _MMPTE_PROTOTYPE {
ULONG Valid : 1;
ULONG ProtoAddressLow : 7;
ULONG ReadOnly : 1; // if set allow read only access.
ULONG WhichPool : 1; 再哪个换页内存池中
ULONG Prototype : 1;
ULONG ProtoAddressHigh : 21; 原型PTE所在偏移
} MMPTE_PROTOTYPE;
typedef struct _MMPTE {
union {
ULONG Long;
HARDWARE_PTE Flush;
MMPTE_HARDWARE Hard;
MMPTE_PROTOTYPE Proto;
MMPTE_SOFTWARE Soft;
MMPTE_TRANSITION Trans;
MMPTE_SUBSECTION Subsect;
MMPTE_LIST List; 系统PTE区用的链表
} u;
} MMPTE;
typedef struct _MMPFN {
union {
WSLE_NUMBER WsIndex; 活动页面处在一个工作集中,为进程或者系统所用的物理页面,这个是信息索引。如果是多进程引用的页面,只是第一个进程的工作集索引
} u1;
PMMPTE PteAddress; 指向PTE所在虚拟地址
union {
ULONG_PTR ShareCount; 对应的PTE的数量 只要大于0就不会被移除
} u2;
union {
struct {
USHORT ReferenceCount; 第一次加入工作集合IO锁定后引用+1,sharecount-1或者IO解锁一次 引用-1
MMPFNENTRY e1; 所有PFN共享的一个结构 描述物理页面的状态,详见下文
};
} u3;
MMPTE OriginalPte;
union {
ULONG_PTR EntireFrame;
struct {
ULONG_PTR PteFrame: 25; 帧编号和标志位
ULONG_PTR InPageError : 1;
ULONG_PTR VerifierAllocation : 1;
ULONG_PTR AweAllocation : 1;
ULONG_PTR Priority : MI_PFN_PRIORITY_BITS;
ULONG_PTR MustBeCached : 1;
};
} u4;
} MMPFN, *PMMPFN;
typedef struct _MMPFNENTRY {
USHORT Modified : 1; 是否已经修改 如果修改,移除这一页之前要先写入辅存
USHORT ReadInProgress : 1; 正在读
USHORT WriteInProgress : 1; 正在写
USHORT PrototypePte: 1; 所引用的PTE是一个原型PTE
USHORT PageColor : 4; 颜色
USHORT PageLocation : 3; MMLISTS 的一个枚举值 指明在那个链表中
USHORT RemovalRequested : 1;
USHORT CacheAttribute : 2;
USHORT Rom : 1;
USHORT ParityError : 1;
} MMPFNENTRY;
typedef struct _MMPFN {
union {
PFN_NUMBER Flink;
} u1;
PMMPTE PteAddress;
union {
PFN_NUMBER Blink;
} u2;
union {
struct {
USHORT ReferenceCount;
MMPFNENTRY e1;
};
} u3;
union {
MMPTE OriginalPte;
};
union {
ULONG_PTR EntireFrame;
struct {
ULONG_PTR PteFrame: 25;
ULONG_PTR InPageError : 1;
ULONG_PTR VerifierAllocation : 1;
ULONG_PTR AweAllocation : 1;
ULONG_PTR Priority : MI_PFN_PRIORITY_BITS;
ULONG_PTR MustBeCached : 1;
};
} u4;
} MMPFN, *PMMPFN;
typedef struct _MMPFN {
union {
PKEVENT Event; 2选一 IO在进行中,这是一个事件,IO完成之后将获得通知。
NTSTATUS ReadStatus; 如果IO错误,这是一个错误码
} u1;
PMMPTE PteAddress;
union {
ULONG_PTR ShareCount;
} u2;
union {
struct {
USHORT ReferenceCount;
MMPFNENTRY e1;
};
} u3;
union {
MMPTE OriginalPte;
LONG AweReferenceCount;
};
union {
ULONG_PTR EntireFrame;
struct {
ULONG_PTR PteFrame: 25;
ULONG_PTR InPageError : 1;
ULONG_PTR VerifierAllocation : 1;
ULONG_PTR AweAllocation : 1;
ULONG_PTR Priority : MI_PFN_PRIORITY_BITS;
ULONG_PTR MustBeCached : 1;
};
} u4;
} MMPFN, *PMMPFN;
typedef struct _MMPFN {
union {
PFN_NUMBER Flink;
} u1;
PMMPTE PteAddress;
union {
PFN_NUMBER Blink;
} u2;
union {
struct {
USHORT ReferenceCount;
MMPFNENTRY e1;
};
} u3;
union {
MMPTE OriginalPte;
LONG AweReferenceCount;
};
union {
ULONG_PTR EntireFrame;
struct {
ULONG_PTR PteFrame: 25;
ULONG_PTR InPageError : 1;
ULONG_PTR VerifierAllocation : 1;
ULONG_PTR AweAllocation : 1;
ULONG_PTR Priority : MI_PFN_PRIORITY_BITS;
ULONG_PTR MustBeCached : 1;
};
} u4;
} MMPFN, *PMMPFN;
typedef enum _MMLISTS {
ZeroedPageList,
FreePageList,
StandbyPageList, //this list and before make up available pages.
ModifiedPageList,
ModifiedNoWritePageList,
BadPageList,
ActiveAndValid,
TransitionPage
} MMLISTS;
typedef struct _MMPFNLIST {
PFN_NUMBER Total;
MMLISTS ListName;
PFN_NUMBER Flink;
PFN_NUMBER Blink;
} MMPFNLIST;
typedef struct _MMCOLOR_TABLES {
PFN_NUMBER Flink;
PVOID Blink;
PFN_NUMBER Count;
} MMCOLOR_TABLES, *PMMCOLOR_TABLES;
typedef struct _MMWSL {
WSLE_NUMBER FirstFree; 第一个空闲项
WSLE_NUMBER FirstDynamic; 指向第一个可以被修剪的页面
WSLE_NUMBER LastEntry; 最后一项
WSLE_NUMBER NextSlot; // The next slot to trim
PMMWSLE Wsle; 一个数组,每个数组描述一个有效地页面,进程内存空间的每一个页面?
WSLE_NUMBER LastInitializedWsle;
WSLE_NUMBER NonDirectCount;
PMMWSLE_HASH HashTable; 散列表
ULONG HashTableSize;
ULONG NumberOfCommittedPageTables;
PVOID HashTableStart;
PVOID HighestPermittedHashAddress;
ULONG NumberOfImageWaiters;
ULONG VadBitMapHint;
USHORT UsedPageTableEntries[MM_USER_PAGE_TABLE_PAGES];
ULONG CommittedPageTables[MM_USER_PAGE_TABLE_PAGES/(sizeof(ULONG)*8)];
} MMWSL, *PMMWSL;
typedef struct _MMWSLENTRY {
ULONG_PTR Valid : 1;
ULONG_PTR LockedInWs : 1;
ULONG_PTR LockedInMemory : 1;
ULONG_PTR Protection : 5;
ULONG_PTR Hashed : 1;
ULONG_PTR Direct : 1;
ULONG_PTR Age : 2;
ULONG_PTR VirtualPageNumber : MM_VIRTUAL_PAGE_SIZE; 页面的虚拟地址所在
} MMWSLENTRY;
typedef struct _MMWSLE {
union {
PVOID VirtualAddress;
ULONG_PTR Long;
MMWSLENTRY e1;
} u1;
} MMWSLE;
typedef struct _MMSUPPORT {
LIST_ENTRY WorkingSetExpansionLinks; 允许修剪的进程将会挂入一个链表MmWorkingSetExpansionHead
LARGE_INTEGER LastTrimTime;
MMSUPPORT_FLAGS Flags;
ULONG PageFaultCount;
WSLE_NUMBER PeakWorkingSetSize;
WSLE_NUMBER GrowthSinceLastEstimate;
WSLE_NUMBER MinimumWorkingSetSize;
WSLE_NUMBER MaximumWorkingSetSize;
struct _MMWSL *VmWorkingSetList;
WSLE_NUMBER Claim; 修剪优先级
WSLE_NUMBER NextEstimationSlot;
WSLE_NUMBER NextAgingSlot;
WSLE_NUMBER EstimatedAvailable;
WSLE_NUMBER WorkingSetSize;
EX_PUSH_LOCK WorkingSetMutex;
} MMSUPPORT, *PMMSUPPORT;