Tuesday, October 15, 2019

Windows Memory Architecture


Virtual Address Space of a Process

Each process has its own address space. 
32-bit processes have 4GB
64-bit processes have 16 EB

Virtual address space is not physical storage. It is just a range of addresses. One does not simply access data without mapping physical storage to portions of the address space. 

Virtual Address Space Partitions

Partitions based on the implementation of the OS.

Null-Pointer Assignment Partition (0x00000000-0x0000FFFF)

This partition is purposely set aside to catch NULL-pointer assignments. Virtual memory in this range may not be reserved with Win32 API functions.

User-Mode Partition

This is the usable address range. The size depends on the CPU architecture. 
x86 0x00010000-0x7FFEFFFF ( ~ 2GB)
x64 0x00000000'00010000 - 0x000007FF'FFFEFFFF (~8192 GB)

Kernel-Mode Partition 

x86 0x80000000-0xFFFFFFFF
x64 0x00000800'00000000 - 0xFFFFFFFF'FFFFFFFF

Contains the OS code (thread scheduling, memory management, file systems support, networking support, device drivers) 

Everything in this partition is shared among all processes.

Regions in Address Space

Most of the address space is free when process is created. 
Use VirtualAlloc to allocate (reserve) regions within the address space. 

Allocation requests rounded to a 64-KB boundary. 
When reserving a region, the size of the region needs to be a multiple of the system's page size (usually 4-KB but IA-64 uses 8-KB). System will round up the request. 

System allocates PEB on behalf of the process.
System also allocates TEB upon thread creation and destruction. 
System can allocate wherever it wants, so PEB and TEB will not likely start on 64-KB boundary (but the size of the regions will still be a multiple of CPU page size) 

Call VirtualFree when the region is no longer needed. 

Committing Physical Storage Within a Region

Physical storage must be committed to a reserved region in order to actually use the region. To commit physical storage, call VirtualAlloc. It is not required to commit physical storage to the entire region. 

Decommit physical storage with VirtualFree.

Physical Storage and the Paging File

RAM is expensive, so OS can make disk space look like RAM. 

A paging file contains virtual memory available to all processes and is located on disk. 

CPU needs to know if memory that a thread is requesting to access is in RAM or on disk. 

OS and CPU save portions of RAM to paging file and loads portions of paging file back into RAM when requested.  

When an application commits memory with VirtualAlloc, that physical space is allocated from a file on the hard disk. 


When thread tries to access data in process' address space:

- if data is in RAM
   translate virtual memory to physical address in memory
- if data not in RAM but in paging file
   page fault

When there is a page fault, OS locates free page of memory in RAM (or frees one if there are none), loads the data from the paging file to the free page in RAM. The OS then updates the translation table to indicate the physical location of the newly loaded data. Try the instruction that caused the page fault again. 

Physical Storage Not Maintained in the Paging File

When invoking an application, system reserves a region of address space and uses the contents (image) of the .exe file as the program's reserved region of address space. 

A memory-mapped file refers to a program's file on the hard disk that the system is using as the physical storage for a region of address space. The system maps the file's image to the reserved region of address space when the PE file is loaded. 

Using multiple page files on different physical hard drives is actually nice because OS can write to multiple drives simultaneously. Add/Remove paging files in Virtual Memory settings. 

System only copies images from removable media to RAM if the image is linked using /SWAPRUN:CD or /SWAPRUN:NET. 

Protection Attributes

Only PAGE_EXECUTE_* memory can execute without throwing access violation (when DEP enabled). 

Copy-on-Write Access

PAGE_WRITECOPY and PAGE_EXECUTE_WRITECOPY are used by OS when mapping PE files to images. Do not pass these to VirtualAlloc. 

When module is first mapped to the process' address space, the system allocates storage for all potential writable pages. Paging file storage not used unless module's writable pages are actually written to. 

When attempting to write to shared block, system finds one of the pages that it allocated when the module was loaded for writing. It then copies contents of the page to the free page so that original page does not have to change. 


Special Access Protection Attribute Flags

PAGE_NOCACHE - disables caching of committed pages (usually for hardware device-drivers)

PAGE_WRITECOMBINE - allows multiple writes to single device to be combined 

PAGE_GUARD - allows an app to be notified when a page has been written to

These attributes are never associated with a region, but can be associated with a block.

A block is a set of contiguous pages that have the same protection attributes and are backed by the same type of physical storage.

GetMappedFileName to get regions backed by data files
Use ToolHelp functions to get regions backed by executable files

Memory Region Types

Free - region not backed by any storage and not reserved
Private - region backed by system's paging file
Image - region backed by memory-mapped image file (.exe or DLL). Not necessarily backed by image file since copy-on-write mechanism will change the region to be backed by a page from the paging file. 

Sources:

Windows via C/C++ - J.Richter, 2008. Chapter 13

No comments:

Post a Comment