Master the fundamental concepts of build a mini kernel through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksFirmware INT 15h AX=E820 returns address ranges and types (usable, reserved, ACPI). Kernels must not place page tables in reserved regions including MMIO holes.
Common ACPI types:
For example, a machine might report usable 0x00000000-0x0009FFFF and 0x00100000-0x7FEFFFFF with a hole for VGA framebuffer.
The E820 memory map you're parsing here is exactly what GRUB passes to every multiboot-compliant kernel, and it's the only way an OS learns which physical addresses are real RAM versus reserved for the VGA buffer, ACPI tables, or memory-mapped PCI devices. Allocating a page from a region you mistakenly marked usable is how kernels corrupt firmware data structures or write straight into device registers.
Before you call the implementation done, walk failure modes on purpose. Test empty structures, single-element edge cases, maximum concurrency, and errno paths that must not crash the program. OS code usually fails in production when happy-path tests pass but invariants break under contention or memory pressure.
Keep structures small and name fields after kernel counterparts when possible. That lets you read man pages and kernel source side by side while you work. Print observable events during development; remove noisy logs once tests pass reliably.
You will call the BIOS hook in your bootloader and store an array of regions for the kernel allocator. This exercise requires marking which ranges are safe for buddy allocation.
At boot, the BIOS describes physical memory with E820 entries (base, length, type). The raw list can be unsorted and can overlap, so the kernel first sanitises it into a clean map. It then reports how much RAM it has and hands out early allocations, which are page-aligned blocks above 1 MiB. Build that pipeline.
cLoading…
Types: 1 usable, 2 reserved, 3 ACPI reclaimable, 4 ACPI NVS, 5 bad memory. Allocated blocks count as a sixth kind, allocated, which ranks above all of them.
entry and every successful alloc.entry 0xBASE: zero length, ignored. Any other type prints entry 0xBASE: unknown type T, treated as reserved and is stored as type 2.0x100000 if the base is lower, then round up to 4 KiB. Take the first region where the block fits, and carve the block from that position. A size of zero prints alloc 0x0: invalid size. If no region fits, print alloc 0xSIZE: out of memory.0x0 if there is none.N KiB if they divide by 1024, otherwise N B.cLoading…
Map lines show an inclusive end, 16 hex digits, and the type name padded to 16 characters.
Input:
cLoading…
Output:
cLoading…
alloc never returns the same memory twice.Hidden tests cover allocations that skip low memory, round up odd sizes, run out of memory or ask for zero bytes, page frames in regions that are not page-aligned, memory above and across 4 GiB, bad memory inside a usable range, unknown types, and zero-length entries.