From 2e9292be6e7903c924449d5b7e2e0d4b46edc6c7 Mon Sep 17 00:00:00 2001 From: ktkk Date: Fri, 7 Nov 2025 10:41:41 +0000 Subject: [PATCH] Refactor and use the Multiboot info struct --- src/main.zig | 44 ++++++++++++++-------- src/multiboot.zig | 96 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 15 deletions(-) create mode 100644 src/multiboot.zig diff --git a/src/main.zig b/src/main.zig index 2e2a80d..dd4f020 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,21 +1,23 @@ const lazy = @import("utils/Lazy.zig").lazy; const Console = @import("Console.zig"); +const MultibootInfo = @import("multiboot.zig").Info; + +const MultibootHeader = packed struct { + magic: i32, + flags: i32, + checksum: i32, + padding: u32, +}; const ALIGN = 1 << 0; const MEMINFO = 1 << 1; const MAGIC = 0x1BADB002; const FLAGS = ALIGN | MEMINFO; - -const MultibootHeader = packed struct { - magic: i32 = MAGIC, - flags: i32, - checksum: i32, - padding: u32 = 0, -}; - export var mutliboot: MultibootHeader align(4) linksection(".multiboot") = .{ + .magic = MAGIC, .flags = FLAGS, .checksum = -(MAGIC + FLAGS), + .padding = 0, }; var stack_bytes: [16 * 1024]u8 align(16) linksection(".bss") = undefined; @@ -24,6 +26,8 @@ export fn _start() callconv(.naked) noreturn { asm volatile ( \\ movl %[stack_top], %%esp \\ movl %%esp, %%ebp + \\ push %%ebx + \\ push %%eax \\ call %[kmain:P] : : [stack_top] "i" (@as([*]align(16) u8, @ptrCast(&stack_bytes)) + @sizeOf(@TypeOf(stack_bytes))), @@ -33,13 +37,23 @@ export fn _start() callconv(.naked) noreturn { var console = lazy(Console, .init); -fn kmain() callconv(.C) void { - std.log.info("This is an info message", .{}); - std.log.debug("This is a debug message!", .{}); - std.log.warn("This is a warning message!", .{}); - std.log.err("This is an error message!", .{}); +fn kmain(magic: u32, info: *const MultibootInfo) callconv(.c) void { + std.debug.assert(magic == MAGIC); - @panic("Uh oh"); + std.log.info("{any}", .{info}); + + if (info.isValid(.boot_loader_name)) { + std.log.info("Booted by {s}", .{info.boot_loader_name}); + } + if (info.isValid(.cmdline)) { + std.log.info("Booted with cmdline \"{s}\"", .{info.cmdline}); + } + + hang(); +} + +fn hang() noreturn { + while (true) asm volatile ("hlt"); } const std = @import("std"); @@ -51,7 +65,7 @@ fn kpanic(msg: []const u8, first_trace_addr: ?usize) noreturn { std.log.err("PANIC: {s}", .{msg}); - while (true) {} + hang(); } pub const std_options = std.Options{ diff --git a/src/multiboot.zig b/src/multiboot.zig new file mode 100644 index 0000000..9863d22 --- /dev/null +++ b/src/multiboot.zig @@ -0,0 +1,96 @@ +const std = @import("std"); + +const BootModule = packed struct { + start: u32, + end: u32, + string: ?[*:0]u8, + reserved: u32, +}; + +pub const Info = packed struct { + flags: std.bit_set.IntegerBitSet(32), + mem_lower: u32, + mem_upper: u32, + boot_device: packed struct { + part3: u8, + part2: u8, + part1: u8, + drive: u8, + }, + cmdline: [*:0]u8, + mods_count: u32, + mods_addr: [*]BootModule, + u: packed union { + aout_sym: packed struct { + tabsize: u32, + strsize: u32, + addr: u32, + reserved: u32, + }, + elf_sec: packed struct { + num: u32, + size: u32, + addr: u32, + shndx: u32, + }, + }, + mmap_length: u32, + mmap_addr: u32, + drives_length: u32, + drives_addr: u32, + config_table: u32, + boot_loader_name: [*:0]u8, + apm_table: u32, + vbe: packed struct { + control_info: u32, + move_info: u32, + mode: u16, + interface_seg: u16, + interface_off: u16, + interface_len: u16, + }, + framebuffer: packed struct { + addr: u64, + pitch: u32, + width: u32, + height: u32, + bpp: u8, + type: u8, + color_info: packed union { + indexed_color: packed struct { + framebuffer_palette_addr: u32, + framebuffer_palette_num_colors: u16, + }, + rgb_color: packed struct { + framebuffer_red_field_position: u8, + framebuffer_red_mask_size: u8, + framebuffer_green_field_position: u8, + framebuffer_green_mask_size: u8, + framebuffer_blue_field_position: u8, + framebuffer_blue_mask_size: u8, + }, + }, + }, + + const Self = @This(); + + pub fn isValid(self: *const Self, comptime field: std.meta.FieldEnum(Self)) bool { + return switch (field) { + .flags => true, + .mem_lower, .mem_upper => self.flags.isSet(0), + .boot_device => self.flags.isSet(1), + .cmdline => self.flags.isSet(2), + .mods_count, .mods_addr => self.flags.isSet(3), + // TODO: .u => either 4 or 5 + .mmap_length, .mmap_addr => self.flags.isSet(6), + .drives_length, .drives_addr => self.flags.isSet(7), + .config_table => self.flags.isSet(8), + .boot_loader_name => self.flags.isSet(9), + .apm_table => self.flags.isSet(10), + .vbe => self.flags.isSet(11), + .framebuffer => self.flags.isSet(12), + else => false, + }; + } +}; +