M2 step 3: route every physical dereference through the physmap
paging.init now builds the physmap (physToVirt(phys)) alongside the low identity map, so both addressing modes resolve during the transition. tableAt (the page-table walk hinge), the pmm bitmap, the framebuffer, LAPIC/IOAPIC/HPET/PM-timer/SPCR MMIO, the ACPI table walk, AML OperationRegions, the ACPI power registers, the user-ELF frame fills, and the AP trampoline arm/disarm all reach physical memory through the physmap. Hal.mapMmio now maps into the physmap and returns the virtual address, so the device layer never learns the layout. boot_info and its pointees are converted at kmain entry. The kernel still links and runs low; identity is the safety net until it's removed. Suite 27/27. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
75bc429aa1
commit
724de7bbd0
+8
-4
@@ -41,7 +41,11 @@ var ap_trampoline_page: u64 = 0;
|
||||
/// pointer to the handoff data. There is no runtime, no stack unwinding, and no
|
||||
/// caller to return to, so this never returns.
|
||||
export fn _start(boot_info: *const BootInfo) callconv(kernel_abi) noreturn {
|
||||
kmain(boot_info);
|
||||
// The loader passes a low physical pointer (its own stack). Reach it — and
|
||||
// everything it points at — through the physmap, so it stays valid once the
|
||||
// low identity map is gone. The physmap base is the same under the loader's
|
||||
// bootstrap tables and the kernel's own.
|
||||
kmain(@ptrFromInt(danos.physToVirt(@intFromPtr(boot_info))));
|
||||
}
|
||||
|
||||
fn kmain(boot_info: *const BootInfo) noreturn {
|
||||
@@ -82,7 +86,7 @@ fn kmain(boot_info: *const BootInfo) noreturn {
|
||||
|
||||
// Summarise the physical memory the loader handed us. The array is danos's
|
||||
// own MemoryRegion, so this is a plain slice — no firmware layout in sight.
|
||||
const regions = @as([*]const danos.MemoryRegion, @ptrFromInt(boot_info.memory_map.regions))[0..boot_info.memory_map.len];
|
||||
const regions = @as([*]const danos.MemoryRegion, @ptrFromInt(danos.physToVirt(boot_info.memory_map.regions)))[0..boot_info.memory_map.len];
|
||||
var usable_pages: u64 = 0;
|
||||
var reserved_pages: u64 = 0; // reserved RAM only — MMIO is device space, not RAM
|
||||
for (regions) |r| {
|
||||
@@ -141,7 +145,7 @@ fn kmain(boot_info: *const BootInfo) noreturn {
|
||||
// mapped) and maps PCIe config space on demand via the VMM. A failure here is
|
||||
// not fatal yet — log it and carry on.
|
||||
const hal = platform.Hal{
|
||||
.mapMmio = arch.mapPage,
|
||||
.mapMmio = arch.mapMmio,
|
||||
.pioRead = arch.pioRead,
|
||||
.pioWrite = arch.pioWrite,
|
||||
};
|
||||
@@ -253,7 +257,7 @@ fn kmain(boot_info: *const BootInfo) noreturn {
|
||||
// idle). init becomes a real schedulable process in M3.
|
||||
if (boot_info.init_len != 0) {
|
||||
status("starting /sbin/init...\n");
|
||||
const image = @as([*]const u8, @ptrFromInt(boot_info.init_base))[0..boot_info.init_len];
|
||||
const image = @as([*]const u8, @ptrFromInt(danos.physToVirt(boot_info.init_base)))[0..boot_info.init_len];
|
||||
scheduler.setPreemption(false);
|
||||
const code = usermode.runInitElf(image);
|
||||
scheduler.setPreemption(true);
|
||||
|
||||
Reference in New Issue
Block a user