Virtual Memory Layout: Windows CE 5.0 vs. Windows Embedded CE 6.0
1/6/2010
Before Windows Embedded CE 6.0, there was a limit of 32 processes, and a 32 MB limit on virtual memory (VM) for each process. Also, all of the processes shared the same 4 GB address space. For CE 6.0, the kernel process resides in the upper 2 GB of the 4-GB (32-bit) virtual memory space, and the bottom 2 GB is unique for each process. There is a limit of about 32,000 processes, due to the number of handles that can be created. The practical limit on the number of processes is bounded by the amount of physical memory.
In previous versions of Windows Embedded CE, the current application executed in slot zero. In CE 6.0, slot zero, and all other process slots, are effectively 2 GB each.
Because virtual memory access is translated into hardware access through the memory management unit (MMU), virtual memory code is CPU-dependent. ARM and x86 CPUs use hardware page tables, so the content of virtual memory is accessed directly by the hardware. Other CPUs use a software translation look-aside buffer (TLB) miss handler for which the content of virtual memory needs to be filled.
The following list shows the design goals for virtual memory management in CE 6.0:
- Large amount of virtual memory per process
- No preset number of processes limit
- Protection between processes
- Mimimalization of CPU-dependent code
- Efficient virtual memory allocation
- Efficient TLB miss handling
The following table shows the CE 6.0 virtual memory map.
Mode | Range | Size | Description | Comments |
---|---|---|---|---|
Kernel |
0xF0000000 - 0xFFFFFFFF |
256 MB |
CPU-specific VM |
System call trap area. Kernel data page. |
Kernel |
0xE0000000 - 0xEFFFFFFF |
256 MB |
Kernel VM, CPU-dependent |
Kernel space virtual memory, unless disallowed by the CPU, such as SHx. |
Kernel |
0xD0000000 - 0xDFFFFFFF |
256 MB |
Kernel VM |
Kernel space virtual memory, shared by all servers and drivers loaded in kernel. |
Kernel |
0xC8000000 - 0xCFFFFFFF |
128 MB |
Object store |
RAM based storage for RAM file system, CEDB databases, and RAM-based registry. Legacy data store. |
Kernel |
0xC0000000 - 0xC7FFFFFF |
128 MB |
Kernel XIP DLLs |
XIP DLLs for the kernel and all servers and drivers loaded in the kernel. |
Kernel |
0xA0000000 - 0xBFFFFFFF |
512 MB |
Statically mapped Uncached |
Direct access to physical memory bypassing the CPU cache. |
Kernel |
0x80000000 - 0x9FFFFFFF |
512 MB |
Statically mapped Cached |
Direct access to physical memory accessed through the CPU cache. |
User |
0x7FF00000 - 0x7FFFFFFF |
1 MB |
Unmapped for protection |
Buffer between user and kernel spaces. |
User |
0x70000000 - 0x7FEFFFFF |
255 MB |
Shared system heap |
Shared heap between the kernel and processes. Kernel and kernel servers can allocate memory in the heap and write to it. Read-only for user processes. Enables a process to get data from a server without having to make a kernel call. |
User |
0x60000000 - 0x6FFFFFFF |
256 MB |
RAM-backed map files |
|
User |
0x40000000 - 0x5FFFFFFF |
512 MB |
User-mode DLLs Code and data |
DLLs are loaded at the bottom of the stack and grow up:
|
User |
0x00010000 - 0x3FFFFFFF |
1 GB |
Process User allocatable VM |
Executable code and data. User VM (heap) virtual allocations:
|
User |
0x00000000 - 0x00010000 |
64 KB |
CPU-dependent user kernel data |
User kernel data is always read-only for user. Depending on CPU, it can be kernel read/write (ARM), or kernel read-only (all others). |
The following list shows some points of note from the table above:
- User-mode DLLs now grow from 0x40000000 upward, instead of downward.
- Users can call VM functions only on the memory that they allocate with VirtualAlloc. They cannot perform VM operations on kernel-allocated VM in user space, such as stacks, memory-mapped file views, and DLL code or data.
- The kernel can read and write to the shared heap area, and user processes can only read to the shared heap area. The purpose of this area is to allow the system to communicate with client processes more efficiently. However, because all processes can read information from the shared heap, do not store any security-sensitive information, such as a password, in the shared heap.
- There is always an unmapped area of at least 64 KB between the regions to protect access span regions.
Virtual Memory Interface for User Processes
There can be only one virtual memory mapped at a time. You cannot access the memory of other processes directly through their virtual memory address window. The virtual memory functions can be used only on an address that was allocated by a process. For example, an application cannot call VirtualProtect on a code address to change its own protection.
The *Ex versions of the following functions are intended for use by servers to access the virtual memory of the client process.
The following functions comprise the virtual memory interface for user processes:
- VirtualAlloc
- VirtualAllocEx
- VirtualFree
- VirtualFreeEx
- VirtualProtect
- VirtualQuery
- WriteProcessMemory
- ReadProcessMemory
- VirtualProtectEx
- VirtualQueryEx
Kernel Virtual Memory Interface
The following *Ex functions take a process handle as a parameter so that you can perform operations on the virtual memory of another process. The following list shows the virtual memory interface for the kernel:
- VirtualCopy
- VirtualCopyEx
- LockPages
- UnlockPages
- CeVirtualSharedAlloc
- AllocPhysMem
- CreateStaticMapping
- VirtualSetAttributes
- DeleteStaticMapping
Benefits of the Virtual Memory Layout
- The number of processes is not limited to 32.
- The amount of memory available to each process is not limited to 32 MB.
- Switching processes on ARM and x86 is faster because it is simpler to make use of the hardware page tables. The time to switch processes for MIPS and SHx remains about the same.
- TLB miss handling is faster on MIPS and SHx because of simpler address space access checking. The time to handle TLB misses on ARM and x86 remains about the same.
Tradeoffs of the Virtual Memory Layout
- The virtual memory for every process is no longer accessible at all times, but the virtual memory for the kernel process and the current process are accessible at all times. Therefore, accessing the memory of another process, particularly buffer parameters that are passed to a server, is no longer as simple as mapping a pointer.
- More complicated reference counting.
- More complicated interprocess communication (IPC) and buffer passing.
See Also
Other Resources
Kernel Functionality Modifications: Windows CE 5.0 vs. Windows Embedded CE 6.0
Kernel API Modifications: Windows CE 5.0 vs. Windows Embedded CE 6.0