Linux – What does the Virtual kernel Memory Layout in dmesg imply

kernellinuxmemory

While going through the "Output of dmesg" I could see a list of values which i am not able to understand properly.

Memory: 2047804k/2086248k available (3179k kernel code, 37232k reserved, 1935k data, 436k init, 1176944k highmem)
virtual kernel memory layout:
    fixmap  : 0xffc57000 - 0xfffff000   (3744 kB)
    pkmap   : 0xff800000 - 0xffa00000   (2048 kB)
    vmalloc : 0xf7ffe000 - 0xff7fe000   ( 120 MB)
    lowmem  : 0xc0000000 - 0xf77fe000   ( 887 MB)
      .init : 0xc0906000 - 0xc0973000   ( 436 kB)
      .data : 0xc071ae6a - 0xc08feb78   (1935 kB)
      .text : 0xc0400000 - 0xc071ae6a   (3179 kB)

From the values i understand that i have 2GB RAM(Physical memory). But rest of the things seems to be Magic Numbers for me.

I would like to know about each one (fixmap, pkmap,.. etc.) in brief(if more doubts, I will post each one as a separate Question)?

Could someone explain that to me?

Best Answer

First off, a 32 bit system has 0xffffffff (4'294'967'295) linear addresses to access a physical location ontop of the RAM.
The kernel divides these addresses into user and kernel space.

User space (high memory) can be accessed by the user and, if necessary, also by the kernel.
The address range in hex and dec notation:

0x00000000 - 0xbfffffff
0 - 3'221'225'471

Kernel space (low memory) can only be accessed by the kernel.
The address range in hex and dec notation:

0xc0000000 - 0xffffffff
3'221'225'472 - 4'294'967'295

Like this:

0x00000000             0xc0000000  0xffffffff 
    |                        |          |
    +------------------------+----------+
    |  User                  |  Kernel  |
    |  space                 |  space   |
    +------------------------+----------+

Thus, the memory layout you saw in dmesg corresponds to the mapping of linear addresses in kernel space.

First, the .text, .data and .init sequences which provide the initialization of the kernel's own page tables (translate linear into physical addresses).

.text : 0xc0400000 - 0xc071ae6a   (3179 kB)

The range where the kernel code resides.

.data : 0xc071ae6a - 0xc08feb78   (1935 kB)

The range where the kernel data segments reside.

.init : 0xc0906000 - 0xc0973000   ( 436 kB)

The range where the kernel's initial page tables reside.

(and another 128 kB for some dynamic data structures.)

This minimal address space is just large enough to install the kernel in the RAM and to initialize its core data structures.

Their used size is shown inside the parenthesis, take for example the kernel code:

0xc071ae6a - 0xc0400000 = 31AE6A

In decimal notation, that's 3'255'914 (3179 kB).


Second, the usage of kernel space after initialization

lowmem  : 0xc0000000 - 0xf77fe000   ( 887 MB)

The lowmem range can be used by the kernel to directly access physical addresses.
This is not the full 1 GB, because the kernel always requires at least 128 MB of linear addresses to implement noncontiguous memory allocation and fix-mapped linear addresses.

vmalloc : 0xf7ffe000 - 0xff7fe000   ( 120 MB)

Virtual memory allocation can allocate page frames based on a noncontiguous scheme. The main advantage of this schema is to avoid external fragmentation, this is used for swap areas, kernel modules or allocation of buffers to some I/O devices.

pkmap   : 0xff800000 - 0xffa00000   (2048 kB)

The permanent kernel mapping allows the kernel to establish long-lasting mappings of high-memory page frames into the kernel address space. When a HIGHMEM page is mapped using kmap(), virtual addresses are assigned from here.

fixmap  : 0xffc57000 - 0xfffff000   (3744 kB)

These are fix-mapped linear addresses which can refer to any physical address in the RAM, not just the last 1 GB like the lowmem addresses. Fix-mapped linear addresses are a bit more efficient than their lowmem and pkmap colleagues. There are dedicated page table descriptors assigned for fixed mapping, and mappings of HIGHMEM pages using kmap_atomic are allocated from here.


If you want to dive deeper into the rabbit hole:
Understanding the Linux Kernel

Related Question