125 lines
2.9 KiB
Zig
125 lines
2.9 KiB
Zig
const lazy = @import("utils/Lazy.zig").lazy;
|
|
const Console = @import("Console.zig");
|
|
|
|
const MultibootInfo = @import("multiboot.zig").Info;
|
|
|
|
const InterruptDescriptorTable = @import("idt.zig").InterruptDescriptorTable;
|
|
const InterruptStackFrame = @import("idt.zig").InterruptStackFrame;
|
|
|
|
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;
|
|
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;
|
|
|
|
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))),
|
|
[kmain] "X" (&kmain),
|
|
);
|
|
}
|
|
|
|
var console = lazy(Console, .init);
|
|
|
|
var idt: InterruptDescriptorTable = .empty;
|
|
|
|
fn kmain(magic: u32, info: *const MultibootInfo) callconv(.c) void {
|
|
std.debug.assert(magic == MAGIC);
|
|
|
|
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});
|
|
}
|
|
|
|
idt.setEntry(.breakpoint, breakpointHandler);
|
|
idt.load();
|
|
|
|
//asm volatile (
|
|
// \\ int3
|
|
// :
|
|
// :
|
|
//);
|
|
|
|
std.log.info("We did not crash!", .{});
|
|
|
|
hang();
|
|
}
|
|
|
|
fn breakpointHandler(stack_frame: *InterruptStackFrame) callconv(.{ .x86_interrupt = .{} }) void {
|
|
std.log.err("breakpoint\n{}", .{stack_frame.*});
|
|
}
|
|
|
|
fn hang() noreturn {
|
|
while (true) asm volatile ("hlt");
|
|
}
|
|
|
|
const std = @import("std");
|
|
|
|
pub const panic = std.debug.FullPanic(kpanic);
|
|
|
|
fn kpanic(msg: []const u8, first_trace_addr: ?usize) noreturn {
|
|
_ = first_trace_addr;
|
|
|
|
std.log.err("PANIC: {s}", .{msg});
|
|
|
|
hang();
|
|
}
|
|
|
|
pub const std_options = std.Options{
|
|
.log_level = .debug,
|
|
.logFn = klog,
|
|
};
|
|
|
|
fn klog(
|
|
comptime level: std.log.Level,
|
|
comptime scope: @Type(.enum_literal),
|
|
comptime format: []const u8,
|
|
args: anytype,
|
|
) void {
|
|
const c = console.get();
|
|
|
|
const color = switch (level) {
|
|
.err => Console.ConsoleColor.light_red,
|
|
.warn => Console.ConsoleColor.light_brown,
|
|
.info => Console.ConsoleColor.light_blue,
|
|
.debug => Console.ConsoleColor.light_green,
|
|
};
|
|
|
|
c.putChar('[');
|
|
c.setColor(color, Console.ConsoleColor.black);
|
|
c.puts(level.asText());
|
|
c.resetColor();
|
|
c.putChar(']');
|
|
|
|
c.putChar(' ');
|
|
|
|
c.puts("(" ++ @tagName(scope) ++ ")");
|
|
|
|
c.putChar(' ');
|
|
|
|
c.printf(format ++ "\n", args);
|
|
}
|