docs: full docs-vs-code audit — fix every stale claim across 40 docs
Every doc verified claim-by-claim against the code by parallel audit agents, then fixed and adversarially re-verified. Two waves of staleness corrected: the originally audited findings (higher-half boot handoff, kernel VFS takeover, fault isolation + claim release + driver restart, AML/S5 moving to ring 3, threading's shipped design, USB+FAT landing) and a second pass of adjacent claims the verifiers caught (smp.md 'not built yet' intro, system-requirements' PS/2-only and no-storage claims, halting.md's red-panic and no-IDT text, testing.md's serial mirroring, router-era vfs-protocol wording, capsule-first boot loading). threading.md now documents the shared-fate gap explicitly: the design says a process dies whole, the kernel today kills only the offending thread. Also fixes three stale code comments (isr.s exceptionHandler, acpi.zig sleepValue, build.zig boot-volume) — comments only, no behavior change.
This commit is contained in:
+13
-8
@@ -14,8 +14,12 @@ behind the [architecture](architecture.md) boundary in `system/kernel/architectu
|
||||
x86_64 uses **4 levels**: PML4 → PDPT → PD → PT, each a 512-entry table, with 9
|
||||
bits of the virtual address indexing each level and the low 12 bits the offset into
|
||||
the final 4 KiB page. Each entry holds a physical address plus flag bits —
|
||||
present, writable, and (bit 63) **no-execute**. danos maps everything with 4 KiB
|
||||
pages: precise, and the extra table memory is negligible against available RAM.
|
||||
present, writable, and (bit 63) **no-execute**. danos maps nearly everything with
|
||||
4 KiB pages: precise, and the extra table memory is negligible against available
|
||||
RAM. (The physmap has since become the one exception: 2 MiB-aligned RAM there is
|
||||
mapped with **2 MiB huge pages** — a PS-bit leaf at the PD level — with 4 KiB
|
||||
pages filling the unaligned edges, so the table footprint scales sanely with big
|
||||
RAM. Kernel segments, heap, user space, and on-demand MMIO stay 4 KiB.)
|
||||
|
||||
## Higher half: the address-space layout
|
||||
|
||||
@@ -27,7 +31,7 @@ address to the low load address in its bootstrap tables and jumps in). The entir
|
||||
alongside a **physmap** — a straight window onto all of physical memory at
|
||||
`physmap_base + phys`. Wherever the kernel needs to touch a physical address (a
|
||||
page-table frame, an ACPI table, a device register), it adds that constant:
|
||||
`system.physToVirt(phys)`. The layout constants live in `system/boot-handoff.zig`:
|
||||
`boot_handoff.physicalToVirtual(phys)`. The layout constants live in `system/boot-handoff.zig`:
|
||||
|
||||
| region | virtual base | PML4 slot |
|
||||
|--------|--------------|-----------|
|
||||
@@ -46,7 +50,7 @@ builds its own precise tables below and abandons them. Because both use the same
|
||||
The address space is built in four passes (`init`):
|
||||
|
||||
1. **All RAM in the physmap, RW + NX.** Every non-MMIO region from the
|
||||
[memory map](memory-map.md) is mapped at `physToVirt(phys)`, read-write and
|
||||
[memory map](memory-map.md) is mapped at `physicalToVirtual(phys)`, read-write and
|
||||
*non-executable*. There is **no low/identity mapping** — the low half is user
|
||||
space. (Frames the kernel touches while still building these tables are reached
|
||||
through the loader's bootstrap physmap, which covers the low 4 GiB; both the
|
||||
@@ -72,7 +76,7 @@ Blanket RW+NX is fine for data but wrong for the kernel's own code, which must b
|
||||
executable — and its code must *not* be writable (W^X: no page is both). We get the
|
||||
right permissions per region straight from the kernel ELF: the **loader already
|
||||
parses the program headers**, so `efi.zig` records each `PT_LOAD` segment's
|
||||
address, size and R/W/X flags into `BootInfo`. Pass 3 re-maps those ranges with
|
||||
address, size and R/W/X flags into `BootInformation`. Pass 3 re-maps those ranges with
|
||||
flags derived from the ELF flags:
|
||||
|
||||
| segment | ELF flags | mapped as |
|
||||
@@ -97,9 +101,10 @@ real memory — turning a whole class of silent bugs into an immediate, located
|
||||
## Switching on, and the on-demand API
|
||||
|
||||
Loading the PML4's physical address into **CR3** switches address spaces and
|
||||
flushes the TLB in one step. This works because the firmware's identity map is
|
||||
still active *while we build*, so freshly allocated table frames are reachable by
|
||||
physical address; afterwards they're covered by pass 1.
|
||||
flushes the TLB in one step. This works because *while we build* the kernel is
|
||||
still running on the loader's bootstrap tables, whose 4 GiB physmap makes freshly
|
||||
allocated table frames reachable at the same `physmap_base + phys` addresses;
|
||||
afterwards they're covered by pass 1.
|
||||
|
||||
`init` keeps the PML4 and the frame allocator around and exposes `map(virt, phys,
|
||||
writable)` / `unmap(virt)` (with `invlpg` TLB invalidation) — the primitive the
|
||||
|
||||
Reference in New Issue
Block a user