booting into the kernel

This commit is contained in:
2026-07-01 19:51:06 +01:00
parent 3c8656fb25
commit ca3c3d131c
5 changed files with 342 additions and 22 deletions
+44 -4
View File
@@ -1,8 +1,48 @@
const std = @import("std");
const Io = std.Io;
const danos = @import("danos");
const BootInfo = danos.BootInfo;
pub fn main() !void {
/// The calling convention used to enter the kernel. Pinned to SysV explicitly:
/// the bootloader is built for the UEFI target, whose C convention is Microsoft
/// x64 (first argument in RCX), while the kernel is SysV (first argument in
/// RDI). Both sides reference this so the `boot_info` pointer lands in the
/// register the other expects. `danos.kernel_abi` re-exports it to the loader.
pub const kernel_abi = danos.kernel_abi;
}
/// Kernel entry point. The bootloader jumps here after `ExitBootServices` with a
/// 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);
}
fn kmain(boot_info: *const BootInfo) noreturn {
// Paint the whole screen so it is visually obvious the kernel took over.
// We honour `pitch` because it can exceed `width * 4`.
const fb = boot_info.framebuffer;
const base: [*]volatile u8 = @ptrFromInt(fb.base);
var y: u32 = 0;
while (y < fb.height) : (y += 1) {
const row: [*]volatile u32 = @ptrCast(@alignCast(base + y * fb.pitch));
var x: u32 = 0;
while (x < fb.width) : (x += 1) row[x] = 0x0033_66cc;
}
hang();
}
/// 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 {
while (true) asm volatile ("hlt");
}
/// Freestanding has no OS to receive a panic, so override std's default panic
/// handler to simply halt. (Later this can print to the framebuffer/serial.)
pub const panic = std.debug.FullPanic(struct {
fn panic(msg: []const u8, first_trace_addr: ?usize) noreturn {
_ = msg;
_ = first_trace_addr;
hang();
}
}.panic);