SilverOS manages memory in two distinct layers. The Physical Memory Manager (PMM) operates at page granularity, keeping track of which 4 KB frames are in use across the entire address space using a flat bitmap. On top of that, the kernel heap provides the familiarDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/pastaboy12345/SilverOS/llms.txt
Use this file to discover all available pages before exploring further.
kmalloc/kfree interface for variable-size allocations within a fixed 4 MB region. Neither layer involves virtual memory or page tables — all addresses are physical, and the kernel runs identity-mapped.
Physical Memory Manager
pmm_init is called early in boot with the Multiboot2 memory map tag, the kernel’s own start and end addresses, and the total detected memory size. It begins by marking every page as reserved (memset(bitmap, 0xFF, ...)), then walks the Multiboot2 memory map and clears the bitmap bit for each page in an AVAILABLE region, skipping any page below kernel_end or below 0x200000 (2 MB). This permanently reserves the first 2 MB, the kernel image, and all Multiboot structures.
The bitmap itself is a 128 KB static array — one bit per 4 KB page, covering up to 4 GB (1 048 576 pages total).
pmm_alloc_page performs a linear scan of the bitmap from index 0 upward, finds the first clear bit, marks it used, decrements free_pages, and zeroes the returned page with memset. It returns NULL when no free pages remain.
pmm_free_page converts the physical address back to a page index and clears the corresponding bit, incrementing free_pages. It is a no-op if the address is out of range or if the page is already marked free — double-frees are silently ignored.
Kernel Heap
The heap is a contiguous region of physical memory managed with a singly-linked list ofheap_block header nodes embedded immediately before each allocation. Each node records the usable byte count (size), a boolean free flag, and a pointer to the next block. Allocations are 16-byte aligned via the ALIGN_UP macro.
heap_init is called once with a base address and byte size. SilverOS passes HEAP_START = 0x1000000 (16 MB) and HEAP_SIZE = 4 MB:
kmalloc(size) — First-fit search. When a suitable block is found, split_block divides it if the surplus is at least 64 bytes plus one header’s worth; otherwise the entire block is handed out. Returns NULL for size == 0 or when the heap is exhausted.
kcalloc(count, size) — Multiplies count by size, calls kmalloc, and zeroes the result with memset. Returns NULL on failure.
krealloc(ptr, new_size) — If ptr is NULL, behaves identically to kmalloc(new_size). If new_size is 0, frees ptr and returns NULL. If the existing block is already large enough, the original pointer is returned unchanged. Otherwise a new block is allocated, the old contents are copied with memcpy, and the old block is freed.
kfree(ptr) — Marks the block free and immediately attempts to coalesce it with the following block and with the preceding block, preventing heap fragmentation over time. kfree(NULL) is a safe no-op.
Checking Available Memory
pmm_get_free_pages returns the live count of unallocated physical pages. The terminal free command converts this to megabytes using the same formula:
pmm_init over the serial port:
Limitations
The current memory subsystem is intentionally minimal:- No virtual memory or page tables. There is no VMM layer, no
mmap, and no address-space isolation between kernel components. Every pointer is a raw physical address. - No memory-mapped I/O abstraction. Drivers access MMIO regions directly by casting physical addresses to pointers. There is no
ioremapequivalent. - Heap is fixed at 4 MB. The heap cannot grow. Once
heap_initis called, the usable kernel heap is bounded by the size passed at initialisation time. - PMM bitmap covers at most 4 GB. Systems with more than 4 GB of RAM will have all memory above 4 GB permanently inaccessible to the PMM.
- No NUMA awareness. The linear bitmap scan always allocates from the lowest available physical address regardless of memory topology.