Our Memory Model
Physical Memory Layout
The kernel reserves the first 8MB for its own use:
0xFFFFFFFF ───────────────────── 4GB
Free for apps
and kernel heap
0x00800000 ───────────────────── 8MB
Kernel Reserved:
- Kernel binary
- GDT / IDT
- Stack
- VGA (0xB8000)
- Page directory
- Page tables
0x00100000 ───────────────────── 1MB ← GRUB loads kernel here
BIOS Reserved
0x000B8000 ───────────────────── ← VGA buffer
0x00000000 ───────────────────── 0
In practice the kernel is much smaller than 8MB, but this gives us comfortable headroom for page tables and future expansion.
Virtual Address Space Division
0xFFFFFFFF ───────────────────── 4GB
User Space
(process-specific)
~1GB
0xC0000000 ───────────────────── 3GB ← Kernel/User boundary
Kernel Space
(always mapped)
Kernel code, data,
page tables
0x00000000 ───────────────────── 0
Kernel Space (0x00000000 – 0xC0000000):
- Always mapped in every process’s page directory
- Accessible only in ring 0
- Contains kernel code, data, page tables
- Identity-mapped for the first 4MB
User Space (0xC0000000 – 0xFFFFFFFF):
- Process-specific mappings
- Accessible from ring 3
- Different content for every process
At the current stage of KFS_3, there are no user processes. The entire address space is kernel-controlled. The boundary matters when we eventually add user-mode execution.
Where kmalloc Lives
The physical allocator (kmalloc) manages a heap region inside the identity-mapped kernel space:
0x00400000 ───────────────────── ← End of identity mapping
Kernel Heap
kmalloc manages here
~0x00200000 ──────────────────── ← Heap starts (after kernel + page tables)
Page tables
Page directory
~kernel_end ──────────────────── ← End of compiled kernel
Kernel Code/Data
0x00100000 ───────────────────── ← GRUB loads kernel
The frame allocator tracks _kernel_end and allocates upward from there.
Where vmalloc Lives
The virtual allocator (vmalloc) maps memory into the high virtual address space, above the identity-mapped region. When a vmalloc call comes in:
- Find a free virtual address range (starting around
0xC0000000or another high address) - Allocate physical frames from the frame allocator
- Map those frames into the virtual address space using
map_page() - Return the virtual address to the caller
The key difference: kmalloc returns a physical address that happens to also be the virtual address (identity mapping). vmalloc returns a virtual address that is mapped to physical pages somewhere else in RAM.