const std = @import("std"); const BootParams = @import("params.zig").BootParams; pub const MULTIBOOT_TAG_ALIGN: usize = 8; pub const MultibootTagType = enum(u32) { end, cmdline, boot_loader_name, module, basic_meminfo, bootdev, mmap, vbe, framebuffer, elf_sections, apm, efi32, efi64, smbios, acpi_old, acpi_new, network, efi_mmap, efi_bs, efi32_ih, efi64_ih, load_base_addr, }; pub const MultibootTag = extern struct { type: u32 align(1), size: u32 align(1), }; pub const MultibootTagCmdline = extern struct { type: u32 align(1), size: u32 align(1), string: [0]u8 align(1), }; pub const MultibootTagModule = extern struct { type: u32 align(1), size: u32 align(1), mod_start: u32 align(1), mod_end: u32 align(1), cmdline: [0]u8 align(1), }; pub const MultibootTagBasicMeminfo = extern struct { type: u32 align(1), size: u32 align(1), mem_lower: u32 align(1), mem_upper: u32 align(1), }; pub const MultibootTagBootdev = extern struct { type: u32 align(1), size: u32 align(1), biosdev: u32 align(1), slice: u32 align(1), part: u32 align(1), }; pub const MultibootMmapEntry = extern struct { addr: u64 align(1), len: u64 align(1), type: u32 align(1), zero: u32 align(1), }; pub const MultibootTagMmap = extern struct { type: u32 align(1), size: u32 align(1), entry_size: u32 align(1), entry_version: u32 align(1), entries: [0]MultibootMmapEntry align(1), }; pub const MultibootVbeInfoBlock = extern struct { external_specification: [512]u8 align(1), }; pub const MultibootVbeModeInfoBlock = extern struct { external_specification: [256]u8 align(1), }; pub const MultibootTagVbe = extern struct { type: u32 align(1), size: u32 align(1), vbe_mode: u16 align(1), vbe_interface_seg: u16 align(1), vbe_interface_off: u16 align(1), vbe_interface_len: u16 align(1), vbe_control_info: MultibootVbeInfoBlock align(1), vbe_mode_info: MultibootVbeModeInfoBlock align(1), }; pub const MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED = 0; pub const MULTIBOOT_FRAMEBUFFER_TYPE_RGB = 1; pub const MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT = 2; pub const MultibootColor = extern struct { red: u8 align(1), green: u8 align(1), blue: u8 align(1), }; pub const MultibootTagFramebufferCommon = extern struct { type: u32 align(1), size: u32 align(1), framebuffer_addr: u64 align(1), framebuffer_pitch: u32 align(1), framebuffer_width: u32 align(1), framebuffer_height: u32 align(1), framebuffer_bpp: u8 align(1), framebuffer_type: u8 align(1), reserved: u16 align(1), }; pub const MultibootTagFramebuffer = extern struct { common: MultibootTagFramebufferCommon align(1), details: extern union { indexed: extern struct { framebuffer_palette_num_colors: u16 align(1), framebuffer_palette: [*]MultibootColor align(1), } align(1), rgb: extern struct { framebuffer_red_field_position: u8 align(1), framebuffer_red_mask_size: u8 align(1), framebuffer_green_field_position: u8 align(1), framebuffer_green_mask_size: u8 align(1), framebuffer_blue_field_position: u8 align(1), framebuffer_blue_mask_size: u8 align(1), } align(1), } align(1), }; pub const MultibootTagElfSections = extern struct { type: u32 align(1), size: u32 align(1), num: u32 align(1), entsize: u32 align(1), shndx: u32 align(1), sections: [*]u8 align(1), }; pub const MultibootTagApm = extern struct { type: u32 align(1), size: u32 align(1), version: u16 align(1), cseg: u16 align(1), offset: u32 align(1), cseg_16: u16 align(1), dseg: u16 align(1), flags: u16 align(1), cseg_len: u16 align(1), cseg_16_len: u16 align(1), dseg_len: u16 align(1), }; pub const MultibootTagEfi32 = extern struct { type: u32 align(1), size: u32 align(1), pointer: u32 align(1), }; pub const MultibootTagEfi64 = extern struct { type: u32 align(1), size: u32 align(1), pointer: u64 align(1), }; pub const MultibootTagSmbios = extern struct { type: u32 align(1), size: u32 align(1), major: u8 align(1), minor: u8 align(1), reserved: [6]u8 align(1), tables: [*]u8 align(1), }; pub const MultibootTagOldAcpi = extern struct { type: u32 align(1), size: u32 align(1), rsdp: [*]u8 align(1), }; pub const MultibootTagNewAcpi = extern struct { type: u32 align(1), size: u32 align(1), rsdp: [*]u8 align(1), }; pub const MultibootTagNetwork = extern struct { type: u32 align(1), size: u32 align(1), dhcpack: [*]u8 align(1), }; pub const MultibootTagEfiMmap = extern struct { type: u32 align(1), size: u32 align(1), descr_size: u32 align(1), descr_vers: u32 align(1), efi_mmap: [*]u8 align(1), }; pub const MultibootTagEfi32Ih = extern struct { type: u32 align(1), size: u32 align(1), pointer: u32 align(1), }; pub const MultibootTagEfi64Ih = extern struct { type: u32 align(1), size: u32 align(1), pointer: u64 align(1), }; pub const MultibootTagLoadBaseAddr = extern struct { type: u32 align(1), size: u32 align(1), load_base_addr: u32 align(1), }; pub fn parseMultibootInfo(multiboot_info: *u8) BootParams { var params = BootParams{ .cmdline = &[_]u8{}, }; var offset: usize = @sizeOf(MultibootTag); while (true) { const tag: *MultibootTag = @ptrFromInt(@intFromPtr(multiboot_info) + offset); if (tag.type == @intFromEnum(MultibootTagType.end)) { break; } switch (@as(MultibootTagType, @enumFromInt(tag.type))) { MultibootTagType.cmdline => { const cmdline_tag: *MultibootTagCmdline = @ptrCast(tag); const sentinel_cmdline = @as([*:0]u8, @ptrCast(&cmdline_tag.string)); params.cmdline = sentinel_cmdline[0..std.mem.len(sentinel_cmdline)]; }, else => {}, } offset += (tag.size + MULTIBOOT_TAG_ALIGN - 1) & ~(MULTIBOOT_TAG_ALIGN - 1); } return params; }