At boot, the initrd's physical range is reserved in the page allocator so we don't hand those frames out for anything else:
- Reservation:
crates/kernel/src/lib.rs:134 (initrd_range passed to memory::init_page_allocator)
- Consumption:
crates/kernel/src/initramfs/mod.rs — find_initrd() turns the range into a &'static [u8] via ValidatedPtr::from_trusted, and extract() walks the cpio and writes every entry into the tmpfs-backed /.
Once extract() returns, the reserved bytes are dead — we've copied everything into tmpfs. For a ~5 MB rootfs.cpio that's ~5 MB of RAM held for the life of the kernel with no consumer.
Why deferred
PageAllocator (crates/mm/src/page_allocator.rs:219) currently exposes only alloc + dealloc. It has no `release_reserved(range)` API. Adding one safely needs:
- A way to convert a reserved range back into free-list pages, taking the allocator's lock.
- A lifetime / pointer-provenance argument that nobody still holds the
&'static [u8] slice returned from find_initrd() once we release. Today that slice leaks out into extract() and is dropped when that fn returns, but a future refactor that stashes the bytes would silently race. Worth a note / test.
Flagged in the PR review for commit 6760dbd but deliberately not fixed there — this is "not broken, but arguably" territory and the fix is invasive enough to deserve its own changeset.
Rough plan
- Add `PageAllocator::release_reserved(range: Range<NonNull>)` (or equivalent) that splices the range into the allocator's free structure.
- At the call site in
initramfs::extract(), after successful extraction, call the release API with the reserved range.
- Unit test: reserve a range, release it, alloc pages and verify the formerly-reserved frames are served.
Created by Claude Code
At boot, the initrd's physical range is reserved in the page allocator so we don't hand those frames out for anything else:
crates/kernel/src/lib.rs:134(initrd_rangepassed tomemory::init_page_allocator)crates/kernel/src/initramfs/mod.rs—find_initrd()turns the range into a&'static [u8]viaValidatedPtr::from_trusted, andextract()walks the cpio and writes every entry into the tmpfs-backed/.Once
extract()returns, the reserved bytes are dead — we've copied everything into tmpfs. For a ~5 MBrootfs.cpiothat's ~5 MB of RAM held for the life of the kernel with no consumer.Why deferred
PageAllocator(crates/mm/src/page_allocator.rs:219) currently exposes onlyalloc+dealloc. It has no `release_reserved(range)` API. Adding one safely needs:&'static [u8]slice returned fromfind_initrd()once we release. Today that slice leaks out intoextract()and is dropped when that fn returns, but a future refactor that stashes the bytes would silently race. Worth a note / test.Flagged in the PR review for commit 6760dbd but deliberately not fixed there — this is "not broken, but arguably" territory and the fix is invasive enough to deserve its own changeset.
Rough plan
initramfs::extract(), after successful extraction, call the release API with the reserved range.Created by Claude Code