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