Above is presented a case where I have only 512 MB of physical memory. What I have read up so far, is that ZONE_NORMAL is mapped to the kernel virtual address space as shown. Essentially I have a 512 MB physical memory, out of which 496 MB worth of ZONE_NORMAL is mapped to the kernel virtual space. Based on this understanding, following are my question:

  • Does, ZONE_NORMAL consists of only kernel space pages ?
  • If ZONE_NORMAL consists only of kernel pages and is mapped completely to the kernel space virtual address range, where do the user space pages get located ?? There does not seem to be any room for user space pages in physical memory.

I am totally mixed up of the case where the physical memory is less than 4GB as shown in this case that I have put forth.

Would really appreciate if someone can throw light on this.


On a 32-bit architecture you have 0xffffffff (4'294'967'295 or 4 GB) linear addresses (not physical space) to refer to a physical address.
Even with only 512 MB of physical storage (the real RAM stick connected to the bus), the kernel will still use 4'294'967'295 (4 GB) linear addresses to calculate the physical ones.

The linux kernel divides these 4 GB (of addresses) into the user space (high memory) and the kernel space (low memory) by 3/1, so the kernel space has 1'073'741'823 (1 GB) of linear addresses to use.

These 1 GB of linear addresses, are only accessible by the kernel and are getting divided up even further.

ZONE_DMA: Contains page frames of memory below 16 MB. This is used for old ISA buses, they are able to address only the first 16 MB of RAM.

ZONE_NORMAL: Contains page frames of memory at and above 16 MB and below 896 MB, these are the addresses, which the kernel can map/access directly.

ZONE_HIGHMEM: Contains page frames of memory at and above 896 MB, page frames above this border are not generally mapped to the kernel space and therefore not directly accessible by the kernel. Page frames from the user space can be temporarily or permanently mapped here.

How much real, physical RAM space is occupied by the different zones depends on the form and number of processes you run.

If you enter free -ml in your console, you can see the usage including low- and high memory:

             total       used       free     shared    buffers     cached
Mem:          3022       2116        905          0        105       1342
Low:           839        196        642
High:         2182       1919        263
-/+ buffers/cache:        667       2354
Swap:         2859         93       2766
| improve this answer | |

The same physical page can be mapped to more than one virtual address.

ZONE_NORMAL consists of pages that can be mapped by the kernel. Most of that memory doesn't belong to the kernel, but the kernel needs to map all memory at some point (not necessarily all at the same time). For example, when the kernel is processing a write system call, it needs to copy data from the user-supplied buffer, which means the buffer must be mapped in the kernel's virtual address space.

The diagram describes the (relatively) simple situation with no high memory. (If you work with high-end ARM devices, now is the time to start learning about high memory.) Then the kernel can map all process memory and all physical memory at the same time.

Here's an example of virtual memory repartition as seen by kernel code (I'm not sure if the exact figures are possible, but the basic idea should be right). That is, I'm describing the meaning of a pointer used by kernel code.

  • 0x00000000..0x00000fff: unallocated. A pointer in this range is invalid.
  • 0x00001000..0xbfffffff: process memory. This is a pointer into the virtual address space of the process that the kernel code under consideration is processing a system call for. A page in that range could be unallocated, or it could be allocated and swapped in (in which case it also has a physical address), or it could be allocated and swapped out (in which case it doesn't have a physical address in RAM, but it has a location in swap).
  • 0xc0000000..0xdfffffff: physical memory. A pointer in this range represents the physical address p-0xc0000000. The interpretation of this pointer does not actually depend on the MMU.
  • 0xe0000000..0xffefffff: unallocated. A pointer in this range is invalid.
  • 0xff000000..0xffffffff: kernel memory. This is a pointer into kernel code or data. A page in this range has an associated physical address, found by the MMU.

I've found Linux Device Drivers to be a good introduction to the innards of the Linux kernel. Ultimately, you may want to turn to the source.

| improve this answer | |
  • Have I "missed" out on the ZONE_HIGHMEM here ? How does it get determined, how much of the physical memory goes to ZONE_NORMAL and how much goes to ZONE_HIGHMEM ? – TheLoneJoker Dec 26 '10 at 17:24
  • @TheLoneJoker: The system in your question doesn't have high memory, so my answer didn't address this complication. – Gilles 'SO- stop being evil' Dec 27 '10 at 12:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.