rumpk/boot/header.zig

74 lines
2.1 KiB
Zig

// SPDX-License-Identifier: LCL-1.0
// Copyright (c) 2026 Markus Maiwald
// Stewardship: Self Sovereign Society Foundation
//
// This file is part of the Nexus Commonwealth.
// See legal/LICENSE_COMMONWEALTH.md for license terms.
//! Rumpk Boot Header
//!
//! Defines the Multiboot2 header for GRUB/QEMU and the bare-metal entry point.
//! Handles BSS clearing and stack initialization before jumping to the Nim kernel.
//!
//! SAFETY: Executed in the earliest boot stage with no environment initialized.
const std = @import("std");
// =========================================================
// Multiboot2 Header (for GRUB/QEMU)
// =========================================================
const MULTIBOOT2_MAGIC: u32 = 0xe85250d6;
const MULTIBOOT2_ARCH_I386: u32 = 0;
const MULTIBOOT2_HEADER_LENGTH: u32 = @sizeOf(Multiboot2Header);
const Multiboot2Header = extern struct {
magic: u32 = MULTIBOOT2_MAGIC,
architecture: u32 = MULTIBOOT2_ARCH_I386,
header_length: u32 = MULTIBOOT2_HEADER_LENGTH,
checksum: u32,
// End tag
end_tag_type: u16 = 0,
end_tag_flags: u16 = 0,
end_tag_size: u32 = 8,
};
fn computeChecksum() u32 {
return @bitCast(-%@as(i32, @bitCast(MULTIBOOT2_MAGIC +% MULTIBOOT2_ARCH_I386 +% MULTIBOOT2_HEADER_LENGTH)));
}
export const multiboot2_header linksection(".multiboot2") = Multiboot2Header{
.checksum = computeChecksum(),
};
// =========================================================
// Entry Point
// =========================================================
extern fn kmain() noreturn;
export fn _start() callconv(.Naked) noreturn {
// Clear BSS, set up stack, then jump to Nim
asm volatile (
\\ // Set up stack
\\ la sp, __stack_top
\\
\\ // Clear BSS
\\ la t0, __bss_start
\\ la t1, __bss_end
\\1:
\\ bge t0, t1, 2f
\\ sd zero, (t0)
\\ addi t0, t0, 8
\\ j 1b
\\2:
\\ // Jump to Nim kmain
\\ call kmain
\\
\\ // Should never return
\\ wfi
\\ j 2b
);
}