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.
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 …
- Microsoft® Windows® Internals, Fourth Edition: Microsoft Windows Server™ 2003, Windows XP, and Windows 2000 (Chapter 7 covers Memory Management)