NT内核的内存分配(PDE与PTE)

来源:互联网 发布:ajax返回的json each 编辑:程序博客网 时间:2024/06/03 17:37

Nt Kernel Memory Allocation

Some important Globals concerning memory.

These globals are defined in ntos/mm/miglobal.c and setin ntos/mm/mminit.c and ntos/mm/i386/init386.c.


GlobalExample ValueNotes
MmHighestUserAddress0x7ffeffffMmUserProbeAddress0x7fff0000One more than MmHighestUserAddressMmSystemRangeStart0x80000000First 4Meg maps directly to [0,0x00400000) physical memoryby a single PDE marked "Large Page".MmNonPagedPoolStart0x8051d000MmPfnDatabase0x83f9f000MmWinStationSpaceBase0xa3000000Base Structure.Current MM_WINSTATION_SPACE struct always found here.This region is per session. 0xa3010000Winstation Space Driver Images Base 0xa3c00000Winstation Space Working Set 0xa4000000Winstation Space Paged Pool 0xa5000000Winstation Space Mapped ViewsMmKStackPoolStart0xa8000000One byte above WinStation Space.
Also known as System PTE Expansion in NT5.0. 0xc0000000Page Table baseMmSystemPteBase0xc0200000PTE for VA 0x80000000MmFirstPteForPagedPool0xc0384000PTE for VA 0xe1000000 (MmPagedPoolStart)MmLastPteForPagedPool0xc0390ffcMmSystemPtesStart[0]0xc03e3000(enum _MMSYSTEM_PTE_POOL_TYPE).SystemPteSpace == 0
PTE for VA 0xf8c00000 (MmNonPagedSystemStart)MmSystemPtesEnd[0]0xc03f94a8MmSystemPtesStart[1]0xc03f94b0(enum _MMSYSTEM_PTE_POOL_TYPE).NonPagedPoolExpansion == 1
PTE for VA 0xfe52c000 (MmNonPagedPoolExpansionStart)MmSystemPtesEnd[1]0xc03fef7c 0xc0400000Page table end + 1 MmPagedPoolStart0xe1000000Fixed AddressMmPagedPoolEnd0xe43fffffMmNonPagedSystemStart0xf8c00000The region known as "system PTE's".MmNonPagedPoolExpansionStart0xfe52c000MmNonPagedPoolEnd0xffbe0000
MmNumberOfSystemPtes0x0000592b(MmSystemPtesEnd[0]-MmSystemPtesStart[0])/4+1
HKLM/System/.../Control/Session_Manager/Memory_Management(DWORD) System_Pages or defaultMmNumberOfPhysicalPages0x00003f6e64M RAMMmWinStationSpaceSize0x05000000Distance from MmWinStationSpaceBase to MmKStackPoolStart.

These are available in kd as follows:

kd> dd MmNumberOfSystemPtes
801565e0 0000592b 83f9f000 00003f6e 00000000

Converting Virtual Address to PTE's.

The page tables are based at 0xc0000000. 32 bits of addressspace must be represented by all PTE's. Each PTE represents12 bits of address space (a 4K page) and itself consumes2 bits (PTE = 4 bytes). So:

    32 - 12 + 2 = 22 bits

of address space is required. Therefore the top of the page table is at 0xc0400000-1.

The relationship between VA, a virtual address, and PTE,the address of the PTE for that address, is:

   VA = (( PTE - PTE_BASE )/ 4 ) * 4K
PTE = ( VA/4K ) * 4 + PTE_BASE

It is useful to note:

   PTE_BASE = 0xc0000000
4K = 0x1000

Because 4K is so nicely represented in hex, the only hardpart for by-hand calculation is the division or multiplication by 4.

For example, the PTE for the base of the PTE table is:

   PTE = ( 0xc0000000 / 0x1000 ) * 4 + 0xc0000000
= 0xc0000 * 4 + 0xc0000000
= 0x300000 + 0xc0000000
= 0xc0300000

By clever coincidence, the page of PTE's starting at this addessis the PDE - a page of PTE's pointing to other pages of PTE's.The PTE of this VA is:

   PTE = ( 0xc0300000 / 0x1000 ) * 4 + PTE_BASE
= 0xc0300c00

This PTE contains the page frame number of the page holding the page directory. However, there must also be some PDE containing this page frame number.Since address translation will work even if each PTE/PDE references a different page frame, the PDE for this address must be the same as thePTE for this address.

The PTE for 0xc0300c00, since it is on the same page as the previouslycalculated PTE, is at 0xc0300c00. This PTE maps itself.

We check this, and that the page frame number in this PTE/PDE isloaded into CR3:

kd> !pte c0300c00
C0300000 - PDE at C0300C00 PTE at C0300C00
contains 00030067 contains 00030067
pfn 00030 --DA--UWV pfn 00030 --DA--UWV

kd> r
eax=00000001 ebx=00725d11 ecx=8014d25c edx=000002f8 esi=000000ae edi=c1979f90
eip=80135b18 esp=801509f4 ebp=80150a04 iopl=0 nv up ei pl nz na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000202
cr0=8001003f cr2=01020004 cr3=00030000

kd>

Remarks on the PTE map.

The previous paragraph remarked that virtual address 0xc0300c00 ismapped by the PTE at the same virtual address. This is explainedas the fixed point of the PTE map. Recall that the PTE map,PTE = h(VA), is linear:

    PTE = h( VA ) 
= ( VA / PAGE_SIZE ) * PTE_SIZE + PTE_BASE

So there is a solution to x = h(x). However, this solution neednot be integral, so this explanation of the fixed point is faulty.

Note, however, that this special address, PTE_f = 0xc0300c00, canbe calculated, for any PTE_BASE, as the third iterate of the maph:

    PTE_f = h( h( h( X ) ) ),  for any virtual address X.

The first iterate maps an arbitrary virtual address to a PTE-alignedvirtual address in the page table; the second iterate maps thisaddress to a PDE in the page directory; and the third iterate mapsthis address the map's fixed point.

This is all by virtue that h is a contracting map:

    X /superset h(X) /superset h(h(X)) /superset ... /superset Y

and the displayed descending chain of address subsets muststablized, since the sets are discrete. Although abstract, this paragraph is a complete proof of thefixed point and illustrates all the conditions necessary for its existence.

For instace, for h to be contracting, the page directory must land page aligned. Hence we find thatPTE_BASE must be aligned on a 4M boundary, or 0x00400000.The length of the chain before stabilization isone more than the layers of page tables. The two level pagetables of the i386 implies that 3 interations of h are necessary.

As an alternative but hypothetical example, consider 256 byte pages of 64 PTE's per page, PTE's still 4 bytes. This would give a four level pagetable where each level uses 6 bits, and the final offset is 8 bits.( 4*6+8=32 ). The fixed point would be calculated by takingh(h(h(h(h(X))))) for any X in the address space.

WinStation space layout.

The following comment is from ntos/mm/citrix/ctxmi.h. OnlyMmWinstationSpaceBase is a global and can be included in thetable of significant globals.

//
// Address Map when MmWinstationSpaceBase == 0xA3000000.
//
// When the system is booted in 2GB mode, these addresses
// change.
//
// MmWinStationSpaceBase+0
// Base structure
// 64K
//
// MmWinStationSpaceBase+0x10000
// Driver images
// 12M-64K (re)based drivers allocated from top down
// WIN32K.SYS based at 0xA3010000 always
//
// MmWinStationSpaceBase+0xC00000
// Working Set
// 4M
//
// MmWinStationSpaceBase+0x1000000
// Paged Pool
// 16M
//
// MmWinStationSpaceBase+0x2000000
// Mapped Views
// 16M
//
// Total
// 48M
//
// MmWinStationSpaceBase+0x3000000
// KSTACK POOL
//
// Total 416M
//
//

The WinstationSpace structures are in kernel space, but the active WinstaionSpace structure is mapped to MmWinStationSpaceBase. Thefirst DWORD of this structure is the signature 0x0ccccccc, so thisvalue should always appear at 0a3000000.

The MM_WINSTATIONSPACE structures are double-linked into a chain rootedat some global. Inside the structures are 20 PDE's which map up to80M of Winstation space. Japanese has more.