Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

  1. Find a free virtual address range (starting around 0xC0000000 or another high address)
  2. Allocate physical frames from the frame allocator
  3. Map those frames into the virtual address space using map_page()
  4. 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.