在内存管理里,绝大部份内存都是分页内存。分页内存就是把内存分成4K页大小的内存块,这些内存块不但可以在物理内存里,也可以切换时保存到硬盘里。这些内存管理里是通过下面的代码进行的,如下:
#001 VOID
#002 INIT_FUNCTION
#003 NTAPI
#004 MmInitializePagedPool(VOID)
#005 {
#006 /*
#007 * We are still at a high IRQL level at this point so explicitly commit
#008 * the first page of the paged pool before writing the first block header.
#009 */
分配一页物理内存作为内存管理结构头。
#010 MmCommitPagedPoolAddress ( (PVOID)MmPagedPoolBase, FALSE );
#011
下面就根据内存数据结构初始化分页管理的内存。
#012 MmPagedPool = RPoolInit ( MmPagedPoolBase,
#013 MmPagedPoolSize,
#014 MM_POOL_ALIGNMENT,
#015 MM_CACHE_LINE_SIZE,
#016 PAGE_SIZE );
#017
#018 ExInitializeFastMutex(&MmPagedPool->Mutex);
#019 }
通过上面函数就可以把分页内存初始化,准备好分页内存给其它函数使用。下面的函数就是从分页内存里分配内存出来的,如下:
#001 /**********************************************************************
#002 * NAME INTERNAL
#003 * ExAllocatePagedPoolWithTag@12
#004 *
#005 * DESCRIPTION
#006 *
#007 * ARGUMENTS
#008 *
#009 * RETURN VALUE
#010 */
#011 PVOID NTAPI
#012 ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType,
#013 IN ULONG NumberOfBytes,
#014 IN ULONG Tag)
#015 {
#016 int align;
#017
根据分配内存大小来选择不同的对齐方式。
#018 if ( NumberOfBytes >= PAGE_SIZE )
#019 align = 2;
#020 else if ( PoolType & CACHE_ALIGNED_POOL_MASK )
#021 align = 1;
#022 else
#023 align = 0;
#024
使用分页内存的线程都需要低于APC_LEVEL级别。
#025 ASSERT_IRQL_LESS_OR_EQUAL(APC_LEVEL);
#026
下面调用双向链表的内存管理器。
#027 return RPoolAlloc ( MmPagedPool, NumberOfBytes, Tag, align );
#028 }
#029
分页内存管理的代码主要文件ntoskrnl/mm/ppool.c里。