rpi5_native_boot.c: carve /reserved-memory out of the Pi 5 memory map
Build / build-amd64-iso (push) Waiting to run
Build / build-aarch64-iso (push) Waiting to run
Build / build-riscv64-img (push) Waiting to run

Previously deferred (rpi5_native_boot.c's own header comment flagged this
as needing interval-splitting logic written blind against hardware not
yet in hand) -- revisited by fetching bcm2712-ds.dtsi directly rather than
assuming reserved-memory was empty or absent. It has one static child
(atf@0, ARM Trusted Firmware's own region) and one dynamic child
(linux,cma, size/alloc-ranges only, no fixed reg) -- the dynamic one is
skipped, nothing fixed to carve and no allocator this early to service it
against anyway.

Adds two fdt.c primitives: fdt_find_node_by_name() (reserved-memory has
neither compatible nor device_type per DT spec) and fdt_next_child_node()
-- one exported symbol, not the two-primitive general sibling-walker
originally sketched, collapsed after review since the only real use here
is "iterate one node's direct children."

collect_reserved_ranges() reads each child's own #address-cells/
#size-cells with a fallback to root's only if absent -- confirmed
necessary, not just defensive: reserved-memory's own declared <2>/<1>
genuinely differs from root's <2>/<2>. emit_region_with_carveouts()
clips a sorted reserved-range list against each RAM region, emitting
alternating EfiConventionalMemory gaps and EfiReservedMemoryType
carve-outs (insertion sort, no libc qsort in freestanding).
RPI5_MAX_MEMMAP_ENTRIES is the exact worst-case count, recomputed rather
than estimated -- the rpi5_mailbox.c buffer-size bug is the standing
lesson for this pattern.

Compile-only-verified; nothing in the existing UEFI/QEMU path calls
rpi5_native_boot(), so this cannot be exercised until real hardware.
Verified 3-arch boot to ok>/zuse)ok>.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YcT3H2PQeyujrzjqS3Var
This commit is contained in:
Robert Allan James
2026-09-04 22:24:57 -04:00
co-authored by Claude Sonnet 5
parent 67e3fb7459
commit 7187d68082
12 changed files with 28050 additions and 50 deletions
+22 -6
View File
@@ -341,12 +341,28 @@ blocker for free.
§3.4, not `compatible`. Required a Makefile fix: `boot/cmdline.c` was only in `LOADER_SRCS_BASE`
(the `.efi` target), not `KERNEL_SRCS_BASE` (the separate `.elf` target `arch/aarch64/*.c`
also wildcards into) — added it there too, a real link failure caught before it could ship.
**Deliberately scoped out, not silently skipped:** `/reserved-memory` is not parsed —
carving reserved sub-ranges out of `/memory`'s span needs interval-splitting logic that
would be written blind against hardware not yet in hand, exactly the kind of code that
hides a bug until real silicon; left as its own future item. `memory/pmm.c`'s Pass 3 only
ever clears pages this file explicitly lists as `EfiConventionalMemory`, so the gap is
"less usable RAM than optimal," never "reserved RAM wrongly marked free." Verified 3-arch
**`/reserved-memory` carving — DONE 2026-09-04.** Originally deferred here as needing
interval-splitting logic written blind against hardware not yet in hand — revisited once an
actual reservation was confirmed to exist rather than assumed either way: fetched
`bcm2712-ds.dtsi` directly and found a real `reserved-memory` node with one static child
(`atf@0`, `reg`-addressed, ARM Trusted Firmware's own region) and one dynamic child
(`linux,cma`, `size`/`alloc-ranges` only, no fixed address — skipped, nothing fixed to carve
and no allocator this early to service it against anyway). `collect_reserved_ranges()`
walks `reserved-memory`'s children via two new `fdt.c` primitives —
`fdt_find_node_by_name()` (needed since `/reserved-memory` has neither `compatible` nor
`device_type` per DT spec §3.5.4) and `fdt_next_child_node()` (one exported symbol, not the
two-primitive general sibling-walker originally sketched — collapsed after review, since
this codebase's only real use is "iterate one node's direct children," not general tree
navigation) — reading each child's own `#address-cells`/`#size-cells` with a fallback to
root's only if absent (confirmed necessary, not just defensive:
`reserved-memory`'s own declared `<2>`/`<1>` genuinely differs from root's `<2>`/`<2>`).
`emit_region_with_carveouts()` clips a sorted reserved-range list against each RAM region,
emitting alternating `EfiConventionalMemory` gaps and `EfiReservedMemoryType` carve-outs
(insertion sort, not `qsort` — freestanding, no libc). `no-map`/`reusable` flags are not
distinguished; every static reservation is excluded from `EfiConventionalMemory` regardless.
`RPI5_MAX_MEMMAP_ENTRIES` is the exact worst-case count
(`RAM_REGIONS * (2*RESERVED_RANGES + 1)`), recomputed rather than estimated — the
`rpi5_mailbox.c` buffer-size bug is the standing lesson for this pattern. Verified 3-arch
boot to `ok>`/`zuse)ok>` — compile-only, same caveat as every item in this list: nothing in
the existing UEFI/QEMU path calls `rpi5_native_boot()`, so this cannot be exercised until
real hardware.