内存管理
物理内存
//申请一页物理地址并挂入到对应的链表
PFN_NUMBER MmAllocPage(ULONG ConsumerType);
首先判断FreeZeroedPageListHead链表是否为空,如果不为空则从FreeZeroedPageListHead取下一个节点,并修改该节点属性为对应类型并挂入对应的链表中,如果FreeZeroedPageListHead为空,则判断FreeUnzeroedPageListHead是否为空,如果不为空,则跟上述一样不过需要多加一步给页面清零的操作,如果两个链表都为空则表明没有足够的物理内存返回NULL
//申请物理页 根据是否愿意进行等待进行处理
NTSTATUS MmRequestPageMemoryConsumer(ULONG consumer,BOOLEAN CanWait, PFN* pfn)
首先取得对应consumer链表中已经获取到的页面数,如果大于等于该类型页面的最大数量-1,则需要根据是否愿意进行等待进行处理,如果不愿意进行等待则直接返回NULL,如果愿意进行等待则调用修剪函数对该类型页面进行修剪。然后如果申请的类型为非分页内存或者当前线程为平衡页面数量的线程,则直接调用MmAllocPage得到物理内存,如果不能得到则蓝屏,如果得到了且当前剩余可用物理页面低于最小设定值,则唤醒内核线程MiBalanceThread进行修剪然后返回。如果类型不为非分页内存且所剩物理页面小于最小值,如果不愿意等待则直接返回NULL,愿意等待咋唤醒内核线程MiBalanceThread进行修剪,将自己的申请页面请求插入到等待页面链表,等待请求被答复。如果没有以上的情况,一般就是调用MmAllocPage获得物理内存。
//释放指定的物理页
NTSTATUS MmReleasePageMemory(consumer, pfn)
如果不存在等待页面请求,则把该页面对应的节点插入到FreeUnzeroedPageList 链表中,如果有请求则响应该请求。