Memory Management – x86 Virtual Address Space

In previous posts, we’ve discussed the Basics of Memory Management, Pool Resources and of course the /3GB Switch.  Today we’re going to take a look at the Virtual Address Space Layouts on a 32-bit system.  We’ll cover the 64-bit system specifics in a later post.  First, let’s cover some basic concepts dealing with the Virtual Address Space in Windows.

There are three main types of data that are mapped into the virtual address space in Windows:

  • per-process private code and data
  • sessionwide code and data
  • systemwide code and data

As we discussed previously, each process has its own private address space that cannot be accessed by other processes unless they have permission to open the process for read or write access.  Threads within the process cannot access virtual addresses outside the private address space unless they map to shared memory sections or use cross-process memory functions.

On systems with multiple sessions, such as Windows 2000 Server with Terminal Services and Windows XP and later operating systems, the sessions space contains information that is global to each session.  A session consists of all the processes and other system objects that represent a single user’s logon session.  We covered Sessions, Desktops and Windows Stations a couple of months ago.  All sessionwide data structures are mapped into a region of system space called session space.  When a process is created, the range of addresses is mapped to the pages appropriate to the session to which the process belongs.

Finally, system space contains the global OS code and data structures that are visible to each process.  The following components are part of the system space:

  • System Code: the OS Image, HAL and Device Drivers used to boot the system
  • System Mapped Views: Used to map the loadable kernel-mode part of the Windows subsystem (Win32k.sys) and its kernel-mode graphics drivers
  • Hyperspace: Used to map the process working set list and temporarily map other physical pages for operations such as zeroing pages, invalidating page table entries and process creation
  • System Working Set List: Structures that describe the system working set
  • System Cache: Used to map files that are open in the system cache
  • Paged Pool: Pageable system memory heap
  • System PTE’s: Pool of system PTE’s used to map system pages such as I/O space, kernel stacks etc.
  • NonPaged Pool: Nonpageable system memory heap
  • Crash Dump Information: Information about the state of a system crash
  • HAL usage: memory reserved for HAL-specific structures

That covers the basic concepts of the virtual address space.  Don’t be too alarmed if you don’t fully understand the individual components of the system space listed above – the key to remember is that there are three main data types to consider: Process, Session and System.  With that in mind, let’s take a look at the layout of Virtual Address Space on a 32-bit (x86) system.

If you recall, each user-mode process on a 32-bit Windows system can have up to 2GB of private address space, with the rest being reserved for the Operating System (we’re assuming that the /3GB switch is not in play at the moment).  The default address space is shown below on the left.  On the right is what the address space would look like if you were to use the /3GB switch.

Basic_x86_Address_Layout image

As you can see, the system-space is dramatically decreased.  For more on how this effects PTE’s and NonPaged Pool (among others) please refer back to our Demystifying /3GB post.  Now, let’s take a look at the different system variables and how they map to system space on systems with and without /3GB:

System Variable Description x86 with 2GB system space x86 with 1GB system space (/3GB)
MmSystemRangeStart Start Address of System Space 0x80000000 0xC0000000
MmSystemCacheWorkingSetList System Working Set List 0xC0000000 Calculated
MmSystemCacheStart Start of System Cache Calculated Calculated
MmSystemCacheEnd End of System Cache Calculated Calculated
MiSystemCacheStartExtra Start of system cache or system PTE extension Calculated 0
MiSystemCacheEndExtra End of system cache or PTE extension 0xC0000000 0
MmPagedPoolStart Start of Paged Pool Calculated Calculated
MmPagedPoolEnd End of Paged Pool Calculated (max = 650MB) Calculated (minimum size = 160MB)
MmNonPagedSystemStart Start of System PTE’s Calculated (lowest value is 0xEB000000) Calculated
MmNonPagedPoolStart Start of NonPaged Pool Calculated Calculated
MmNonPagedPoolExpansionStart Start of NonPaged Pool Expansion Calculated Calculated
MmNonPagedPoolEnd End of NonPaged Pool 0xFFBE0000 0xFFBE0000

That brings us to the end of our overview of the 32-bit Virtual Address Space.  We’ll go over the 64-bit address spaces in a future post.  Until next time …

Additional Resources:

CC Hameed