Skip to main content

Overview

Aurora OS memory management consists of three layers:
  1. Physical Memory Allocator - Bitmap-based page frame allocator
  2. Paging (Virtual Memory) - 4-level page tables for x86_64
  3. Kernel Heap - kmalloc/kfree with slab caches
Aurora uses 4 KiB pages and supports up to 4 GiB of RAM with the bitmap allocator.

Physical Memory Allocator

Bitmap-based allocator managing 4 KiB page frames. Source: kernel/src/mm/phys.c

Architecture

  • Page Size: 4096 bytes (4 KiB)
  • Max Pages: 1,048,576 (4 GiB total)
  • Bitmap Size: 128 KiB (1 bit per page)
  • Allocation Strategy: O(1) amortized with free hint
struct phys_mmap_entry {
    uint64_t base;      // Physical address
    uint64_t length;    // Region size in bytes
    uint64_t type;      // PHYS_MMAP_USABLE, etc.
};

Memory Map Types

PHYS_MMAP_USABLE
0
Usable RAM - available for allocation.
PHYS_MMAP_RESERVED
1
Reserved by firmware/BIOS.
PHYS_MMAP_ACPI_RECLAIMABLE
2
ACPI tables - reclaimable after parsing.
PHYS_MMAP_KERNEL_AND_MODULES
6
Kernel ELF and loaded modules.
PHYS_MMAP_FRAMEBUFFER
7
GOP framebuffer memory.
Source: kernel/src/mm/phys.h:15-23

phys_init_mmap

Initialize physical memory allocator with memory map from bootloader (Limine/Multiboot2).
void phys_init_mmap(struct phys_mmap_entry *entries, size_t count);
entries
struct phys_mmap_entry*
Array of memory regions from bootloader.
count
size_t
Number of memory map entries.
Behavior:
  1. Marks all pages as allocated (safe default)
  2. Frees pages in regions with type == PHYS_MMAP_USABLE
  3. Reserves first 1 MiB (BIOS/bootloader area)
  4. Page-aligns region boundaries
Source: kernel/src/mm/phys.c:50-87

phys_alloc

Allocate a single 4 KiB physical page frame.
void *phys_alloc(void);
return
void*
Physical address of allocated page, or NULL if out of memory.
Algorithm:
  • Uses free hint for O(1) amortized allocation
  • Scans bitmap starting from next_free_hint
  • Updates hint after allocation
for (size_t j = 0; j < total_pages; j++) {
    size_t i = (next_free_hint + j) % total_pages;
    if (!bitmap_test(i)) {
        bitmap_set(i);
        next_free_hint = (i + 1) % total_pages;
        return (void *)(i * PAGE_SIZE);
    }
}
return NULL;  // Out of memory
Source: kernel/src/mm/phys.c:89-100

phys_free

Free a physical page frame.
void phys_free(void *page);
page
void*
Physical address (must be page-aligned).
Behavior:
  • Clears bitmap bit for the page
  • Updates free hint if freed page is before current hint (optimization)
Source: kernel/src/mm/phys.c:102-109

phys_reserve_range

Reserve a specific physical address range (for kernel, modules, framebuffer).
void phys_reserve_range(uint64_t base, uint64_t length);
base
uint64_t
Starting physical address.
length
uint64_t
Size in bytes.
Source: kernel/src/mm/phys.c:119-127

Virtual Memory (Paging)

4-level page tables for x86_64 with higher-half kernel mapping. Source: kernel/src/mm/paging.c

Architecture

  • Levels: PML4 → PDPT → PD → PT → Page (4 levels)
  • Kernel Virtual Address: 0xFFFFFFFF80000000 (higher-half)
  • Identity Map: First 2 MiB for boot transition
  • Page Size: 4 KiB (also supports 2 MiB large pages)
Aurora uses higher-half kernel design: kernel mapped at high virtual addresses, user space at low addresses.

Page Table Entry Flags

#define PAGE_PRESENT  (1ULL << 0)  // Page is present in memory
#define PAGE_WRITABLE (1ULL << 1)  // Page is writable
#define PAGE_USER     (1ULL << 2)  // User-mode accessible
#define PAGE_NX       (1ULL << 63) // No-execute (requires EFER.NXE)
#define PAGE_COW      (1ULL << 9)  // Copy-on-write (software flag)
Source: kernel/src/mm/paging.h:12-16

paging_init

Initialize kernel page tables with higher-half mapping.
void paging_init(void);
Behavior:
  1. Allocates new PML4 table
  2. Identity maps first 2 MiB (for boot): 0x0 → 0x0
  3. Higher-half maps first 2 MiB: 0xFFFFFFFF80000000 → 0x0
  4. Uses 2 MiB large pages for efficiency
  5. Loads new page table into CR3
Source: kernel/src/mm/paging.c:92-116

paging_map

Map a virtual page to a physical page in the current address space.
void paging_map(uint64_t virt, uint64_t phys, uint64_t flags);
virt
uint64_t
Virtual address (page-aligned).
phys
uint64_t
Physical address (page-aligned).
flags
uint64_t
Combination of PAGE_* flags.
Behavior:
  1. Walks 4-level page table hierarchy
  2. Allocates missing intermediate tables on-demand
  3. Sets final page table entry: pt[idx] = phys | flags | PAGE_PRESENT
  4. Invalidates TLB entry with invlpg
Source: kernel/src/mm/paging.c:118-138

paging_unmap

Unmap a virtual page.
void paging_unmap(uint64_t virt);
virt
uint64_t
Virtual address to unmap.
Behavior:
  • Clears page table entry
  • Flushes TLB with invlpg
  • Does not free physical page (caller must call phys_free)
Source: kernel/src/mm/paging.c:140-155

paging_clone_kernel

Create a new page table for a process by cloning kernel mappings.
uint64_t paging_clone_kernel(void);
return
uint64_t
Physical address of new PML4 table, or 0 on failure.
Behavior:
  • Allocates new PML4 table
  • Copies kernel half (PML4 entries 256–511) by reference
  • Leaves user half (entries 0–255) empty
  • Used by proc_create()
Source: kernel/src/mm/paging.c:161-175

paging_clone_address_space

Fork a complete address space (for fork() syscall).
uint64_t paging_clone_address_space(uint64_t src_pml4_phys);
src_pml4_phys
uint64_t
Physical address of source PML4 (parent process).
return
uint64_t
Physical address of cloned PML4, or 0 on failure.
Behavior:
  1. Clones kernel half (entries 256–511) by reference
  2. Deep-copies user half (entries 0–255):
    • Allocates new physical pages
    • Copies page contents with page_copy_4k()
  3. Preserves page flags (writable, user, NX, COW)
Copy-on-Write (COW) optimization planned but not yet implemented. Current fork does eager copy.
Source: kernel/src/mm/paging.c:177-198

paging_map_in

Map a page in a specific PML4 (not current). Used for loading ELF into new process.
void paging_map_in(uint64_t pml4_phys, uint64_t virt, 
                   uint64_t phys, uint64_t flags);
pml4_phys
uint64_t
Target PML4 physical address.
virt
uint64_t
Virtual address to map.
phys
uint64_t
Physical address.
flags
uint64_t
Page flags.
Source: kernel/src/mm/paging.c:200-221

paging_virt_to_phys

Translate virtual address to physical address.
uint64_t paging_virt_to_phys(uint64_t virt);
return
uint64_t
Physical address, or 0 if not mapped.
Behavior:
  • Walks page table hierarchy
  • Handles 2 MiB large pages
  • Returns 0 if any level is not present
Source: kernel/src/mm/paging.c:227-242

Kernel Heap (kmalloc)

Dynamic memory allocator for kernel with slab caches for small objects. Source: kernel/src/mm/heap.c

Architecture

  • Small Allocations (≤2048 bytes): Slab caches
  • Large Allocations: Free-list heap with coalescing
  • Alignment: 16-byte aligned
  • Thread Safety: Spinlock protected
static const size_t slab_sizes[] = {
    16, 32, 64, 128, 256, 512, 1024, 2048
};

heap_init

Initialize kernel heap allocator.
void heap_init(uint64_t start, size_t size);
start
uint64_t
Starting virtual address of heap region.
size
size_t
Total heap size in bytes.
Behavior:
  • Initializes free-list with single large block
  • Creates 8 slab caches for sizes 16–2048 bytes
  • Each slab cache has 32 KiB backing memory
Source: kernel/src/mm/heap.c:40-50

kmalloc

Allocate kernel memory.
void *kmalloc(size_t size);
size
size_t
Number of bytes to allocate.
return
void*
Pointer to allocated memory, or NULL if out of memory.
Algorithm:
  1. Round size up to 16-byte boundary
  2. Try slab cache if size ≤ 2048
  3. Fall back to free-list heap
  4. Splits blocks if remaining space > 16 bytes
  5. Thread-safe with spinlock
Source: kernel/src/mm/heap.c:52-87

kfree

Free kernel memory.
void kfree(void *ptr);
ptr
void*
Pointer returned by kmalloc().
Behavior:
  • Automatically detects slab vs. free-list allocation
  • Coalesces adjacent free blocks
  • Thread-safe with spinlock
Source: kernel/src/mm/heap.c:89-120

Memory Layout

0x0000000000000000  ┌─────────────────────┐
                    │   User Space        │  (0–256 PML4 entries)
                    │   (per-process)     │
0x0000800000000000  ├─────────────────────┤
                    │   Canonical Hole    │
0xFFFF800000000000  ├─────────────────────┤
                    │   Kernel Space      │  (256–511 PML4 entries)
0xFFFFFFFF80000000  │   Higher-Half       │  ← Kernel code/data
                    │                     │
0xFFFFFFFFFFFFFFFF  └─────────────────────┘

Performance Characteristics

Physical Allocation

Time: O(1) amortizedFree hint avoids full bitmap scan.

Page Mapping

Time: O(1)4-level lookup, allocates missing tables.

kmalloc (small)

Time: O(1)Slab allocator for ≤2048 bytes.

kmalloc (large)

Time: O(n)Free-list scan, n = number of blocks.

Security Features

  • KASLR: Kernel Address Space Layout Randomization
  • ASLR: User-space address randomization (per-process mmap_next)
  • NX Pages: No-execute protection via PAGE_NX flag
  • COW: Copy-on-write for fork (software flag defined)
References:
  • ASLR: kernel/src/proc/process.c:72-74
  • KASLR: STATUS.md:20


References

Build docs developers (and LLMs) love