250 lines
6.1 KiB
Zig
250 lines
6.1 KiB
Zig
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;
|
|
} |