Move to multi arch support and added memory map

This commit is contained in:
2026-07-03 11:11:19 +01:00
parent c2435760c4
commit 628c4f6d57
11 changed files with 423 additions and 41 deletions
+16 -13
View File
@@ -15,12 +15,14 @@ safely, until the machine is reset or powered off.
## The core of it: `hlt`
Everything comes down to one x86 instruction. In `src/main.zig`:
Everything comes down to one x86 instruction. It's CPU-specific, so it lives in
the arch module, `src/arch/x86_64/cpu.zig` (see [arch.md](arch.md)), and the
generic kernel calls it as `arch.halt()`:
```zig
/// Stop the CPU. `hlt` in a loop parks the core at near-zero power until the
/// next interrupt; we loop because `hlt` returns when one arrives.
fn hang() noreturn {
/// Park the core forever. `hlt` drops it into a low-power idle until the next
/// interrupt; the loop re-halts on every wake so the stop is permanent.
pub fn halt() noreturn {
while (true) asm volatile ("hlt");
}
```
@@ -71,7 +73,7 @@ makes us robust to all of them.)
## `noreturn`: telling the compiler it's the end
`hang()` is typed `noreturn` — a real Zig type meaning "this function never gives
`halt()` is typed `noreturn` — a real Zig type meaning "this function never gives
control back to its caller." That isn't decoration; it changes how the compiler
treats the call:
@@ -82,26 +84,27 @@ treats the call:
jumps back out.
You can see the chain in `src/main.zig`: `_start` is `noreturn`, it calls
`kmain` which is `noreturn`, which ends by calling `hang()` which is `noreturn`.
The "never returns" property is threaded all the way down.
`kmain` which is `noreturn`, which ends by calling `arch.halt()` which is
`noreturn`. The "never returns" property is threaded all the way down.
## Where danos halts
There are three halt sites, and they're all the same idea:
1. **Normal end of kernel work** — `kmain` prints its status, then calls `hang()`:
1. **Normal end of kernel work** — `kmain` prints its status, then calls
`arch.halt()`:
```zig
con.write("\nkernel initialised; nothing left to do, halting.\n");
hang();
arch.halt();
```
There's genuinely nothing more to do yet, so the kernel parks itself.
2. **Kernel panic** — the freestanding panic handler has no OS to report to, so
it prints the message in red (if the console is up) and halts via the same
`hang()`. A panic is unrecoverable here, so stopping the machine — rather than
limping on with corrupted state — is the safe response.
`arch.halt()`. A panic is unrecoverable here, so stopping the machine — rather
than limping on with corrupted state — is the safe response.
3. **Bootloader failure** — in `src/efi.zig`, if `boot()` fails *before* handing
off to the kernel, `main` logs the error and parks the machine with the same
@@ -116,8 +119,8 @@ There are three halt sites, and they're all the same idea:
};
```
(Here it's an inline loop rather than `hang()` because `hang` lives in the
kernel, which the loader is a separate binary from.)
(Here it's an inline loop rather than `arch.halt()` because that lives in the
kernel's arch module, and the loader is a separate binary from the kernel.)
## Summary