process address space(virtual address space)
4GB +---------------+
| 512MB |
+---------------+ <------+ physical memory
| 512MB | |
3GB +---------------+ <--+ +---> +------------+
| | | | 512 MB |
| ///// | +-------> +------------+
| |
0GB +---------------+
- When the RAM is 512MB then whole of RAM is linearly mapped to the 512MB of the lower 512 MB of the kernel virtual space.
- The virtual address space of Kernel is divided into two parts 1. Low memory 2. High Memory.
- The first 896MB constitute the low memory region or LOWMEM.
- The top 128 MB is called high memory region or HIGHMEM.
- The first 16MB of LOWMEM is reserved for DMA usage.
- There are some zones of physical memory:
- ZONE_DMA - Contains page frames of memory below 16 MB
- ZONE_NORMAL - Contains page frames of memory at and above 16 MB and below 896 MB
- ZONE_HIGHMEM - Contains page frames of memory at and above 896 MB
- So, if you have 512 MB, your ZONE_HIGHMEM will be empty, and ZONE_NORMAL will have 496 MB of physical memory mapped.
physical memory
process address space +------> +------------+
| | 3200 M |
| | |
4GB +---------------+ <-----+ | HIGH MEM |
| 128 MB | | |
+---------------+ <---------+ | |
+---------------+ <------+ | | |
| 896 MB | | +--> +------------+
3GB +---------------+ <--+ +-----> +------------+
| | | | 896 MB |
| ///// | +---------> +------------+
| |
0GB +---------------+
- As we can see from the diagram the physical memory above 896MB is mapped to the 128MB of the HIGHMEM region.
- When we request a large chunk of memory from physical space using vmalloc() then we get it from HIGHMEM also ,that's why the physical pages that we get are not contiguous.
- For a user-space application, if you print out the pointer address you defined, it should be one of the virtual addresses out of the (0-3GB) range.
- What about kernel? what if print a pointer address in kernel? is it always from kernel address space? The answer is no ... since kernel can access user space address, depending on the pointer, it can be from either.
- To distinguish between kernel space and user space address is easy, if it fall into 0-3GB, then it is from user-space, otherwise, it is from kernel.The programmer sees virtual address only.
- To make things clear from user point of view lets see the user space addresses after compiling the program.
+----------------------+ <--- 0xBFFF FFFF (=3GB)
| environment variable |
|----------------------| <--- 0xBFFF FD0C
| stacks (down grow) |
| | |
| v |
|----------------------|
| |
| // free memory |
| |
| |
|----------------------| <--------------------
| myprogram.o | |
|----------------------| |
| mylib.o | |
|----------------------| executable image
| myutil.o | |
|----------------------| |
| library code (libc) | |
|----------------------| <--------------------
| | 0x8000 0000 (=2GB)
| |
| other memory |
| |
+----------------------+
PAGE_OFFSET = 0xC8000000 = 3GB
For a 512MB system, the virtual address for kernel will be from 3GB ~ PAGE_OFFSET + 512MB