added physical memory manager
This commit is contained in:
+25
-9
@@ -32,10 +32,11 @@ Defined in `src/root.zig`, the shared loader↔kernel contract:
|
||||
```zig
|
||||
pub const MemoryKind = enum(u32) {
|
||||
usable, // free RAM the kernel may allocate
|
||||
reserved, // firmware / MMIO / kernel image — never hand out
|
||||
reserved, // firmware / kernel image — real RAM, but never hand out
|
||||
reclaimable, // usable once boot-time structures are done with
|
||||
acpi_tables, // parse, then reclaim
|
||||
acpi_nvs, // preserve across sleep
|
||||
mmio, // device registers / reserved address space — not RAM at all
|
||||
};
|
||||
|
||||
pub const MemoryRegion = extern struct {
|
||||
@@ -70,12 +71,20 @@ pub const BootInfo = extern struct {
|
||||
|
||||
Two functions in `src/efi.zig`, called from `exitBootServices`:
|
||||
|
||||
- **`classify`** maps each UEFI memory type to a `MemoryKind`:
|
||||
- **`classify`** maps each UEFI descriptor to a `MemoryKind`:
|
||||
`conventional_memory → usable`; `boot_services_code`/`boot_services_data →
|
||||
reclaimable` (free once we've exited); `acpi_reclaim_memory → acpi_tables`;
|
||||
`acpi_memory_nvs → acpi_nvs`; **everything else → reserved** (the safe default).
|
||||
Our own `loader_data` — the kernel image and these buffers — falls into
|
||||
`reserved`, so it won't be handed out until the kernel deliberately reclaims it.
|
||||
|
||||
One subtlety: **a region that isn't writeback-cacheable (the descriptor's `wb`
|
||||
attribute) is classified `mmio` regardless of type.** UEFI overloads
|
||||
`reserved_memory_type` for both reserved RAM *and* reserved address-space windows
|
||||
(PCIe config space, device BARs); the cache attribute is what actually tells them
|
||||
apart, since only real RAM is writeback-cacheable. Without this, a QEMU q35 guest
|
||||
reports ~12 GiB of "reserved" that is really a PCIe address hole near the 1 TB
|
||||
mark — not memory at all.
|
||||
- **`convertMemoryMap`** walks the UEFI descriptors (striding by
|
||||
`descriptor_size`, *not* `@sizeOf`), classifies each, and writes danos
|
||||
`MemoryRegion`s into an output buffer, coalescing adjacent same-kind regions.
|
||||
@@ -111,17 +120,24 @@ for (regions) |r| {
|
||||
}
|
||||
```
|
||||
|
||||
Today `kmain` just prints the region count and total usable RAM — enough to prove
|
||||
the handoff works. Booted in QEMU with 128 MiB, it reports something like:
|
||||
`kmain` summarises the map to prove the handoff works. Booted in QEMU with
|
||||
128 MiB, it reports:
|
||||
|
||||
```
|
||||
mem regions: 35
|
||||
usable RAM : 77 MiB
|
||||
danos: physical memory
|
||||
total RAM : 0.12 GiB (127 MiB) - RAM the firmware reported
|
||||
usable : 77 MiB - free now; owned by the frame allocator
|
||||
reclaimable: 44 MiB - UEFI boot-services memory, free after exit
|
||||
reserved : 6 MiB - kernel image, ACPI, runtime services
|
||||
regions : 35 - entries in the firmware memory map
|
||||
```
|
||||
|
||||
with the balance being `reclaimable` boot-services memory (~44 MiB) and a large
|
||||
`reserved` span that is mostly MMIO address space, not RAM. Those figures summing
|
||||
back to ~128 MiB is the sanity check that nothing was dropped.
|
||||
The `usable` figure is only ~77 of ~127 MiB because most of the rest is
|
||||
`reclaimable` boot-services memory — real RAM we'll take back once we implement
|
||||
reclaiming, not memory that's gone. `total` counts only writeback-cacheable RAM,
|
||||
so the ~12 GiB PCIe address hole is excluded (it's `mmio`), and the three RAM
|
||||
categories summing back to the firmware's total is the sanity check that nothing
|
||||
was dropped.
|
||||
|
||||
## How Raspberry Pi will fit
|
||||
|
||||
|
||||
Reference in New Issue
Block a user