Linux Addressing
The address space in linux is of two kinds
- Physical Address Space
- Virtual Address Space
Physical Address Space addresses the contents of the RAM directly.
Virtual Address Space addresses the contents of the RAM not directly, but through a MMU (Memory Management Unit)
The reason why we go with Virtual address space is threefold
- To provide security between applications. Imagine what would happen if one process could read the memory of another process
- To provide sandboxing capabilities. Example would be stack of one process remains different from the stack of another process.
- To provide for encapsulation. The userspace process can just do what it needs to do and not worry about memory management.
If a system is 32 bit , then there are 2³² virtual addresses (4GB) that are possible. Now every process on this 32 bit machine basically thinks its got 4 GB of memory.
Now to add to the complexity :)
Now this 4 GB virtual address space is divided into
- Userspace virtual address — From 0 GB to 3 GB
- Kernel virtual address — From 3 GB to 4GB
Now almost every userspace process is going to make a couple of system calls be it to print on the screen , to allocate memory, to take input from user or maybe even to establish a network connection.
So the kernel virtual address space is the mapping of physical address of the kernel on the RAM. This is almost a 1 to 1 mapping except for some conditions which we will talk about later in this article.
Now this kernel virtual address is further divided into
- LOWMEM — From 3GB to 3GB + 896 MB ( The First 16 MB in LOWMEM is for DMA)
- HIGHMEM — From 3GB+897M to 4GB
The physical memory is also divided into ZONES
- ZONE_DMA — From 0MB to 16MB
- ZONE_NROMAL — From 16MB — 896 MB
- ZONE_HIGHMEM — From 897MB to remaining physical memory.
So how exactly is this kernel virtual addresses mapped to the physical memory?
Let me show it to you with the help of a picture
The 128 MB of HIGHMEM is mapped to ZONE_HIGHMEM in the physical memory, this basically means that if we need large amounts of memory in the kernel its given from ZONE_HIGHMEM and if memory is allocated in this region it is not going to be contiguous. ( Like for example a valloc call).
The reason for this is , ZONE_NORMAL and ZONE_DMA are never going to be swapped out and is exclusively reserved for the kernel, whereas ZONE_HIGHMEM is for the userspace process also. ( valloc therefore is slow and results in a lot of thrashing, if you need contiguous memory you need to use kalloc)
Consider an edge case when the RAM present is around 512 MB. In that case ZONE_DMA + ZONE_NORMAL is going to be 512 MB and ZONE_HIGHMEM is going to be 0.