109 lines
3.5 KiB
Zig
109 lines
3.5 KiB
Zig
const builtin = @import("builtin");
|
|
const std = @import("std");
|
|
const assert = std.debug.assert;
|
|
|
|
usingnamespace @import("panic.zig");
|
|
|
|
const apic = @import("apic.zig");
|
|
const bootboot = @import("bootboot.zig");
|
|
const cpu = @import("cpu.zig");
|
|
const framebuffer = @import("framebuffer.zig");
|
|
const global = @import("global.zig");
|
|
const kernel = @import("kernel.zig");
|
|
const lock = @import("lock.zig");
|
|
const log = @import("logger.zig").log;
|
|
const memory = @import("memory.zig");
|
|
const panic_mod = @import("panic.zig");
|
|
const paging = @import("paging.zig");
|
|
const types = @import("types.zig");
|
|
|
|
const kernel_stack_size: usize = 8 * 4096;
|
|
|
|
var ap_lock: lock.SpinLock = lock.SpinLock.init();
|
|
var init_stack: [8192]u8 align(std.Target.stack_align) = undefined;
|
|
|
|
fn init() noreturn {
|
|
// Initialize framebuffer
|
|
|
|
// TODO Possible bootboot bug
|
|
const fb_size = if (bootboot.bootboot.fb_size != 0) bootboot.bootboot.fb_size else bootboot.bootboot.fb_width * bootboot.bootboot.fb_height * 4;
|
|
global.framebuffer = framebuffer.Framebuffer.init(
|
|
@ptrCast([*]volatile u8, &bootboot.fb)[0..fb_size],
|
|
bootboot.bootboot.fb_width,
|
|
bootboot.bootboot.fb_height,
|
|
bootboot.framebuffer_pixel_type() catch @panic("Unsupported framebuffer pixel type"),
|
|
);
|
|
global.framebuffer.?.clear();
|
|
|
|
global.framebuffer_stream = global.framebuffer.?.outStream();
|
|
global.log_target = &global.framebuffer_stream.?.stream;
|
|
|
|
log(.Debug, "Framebuffer ({}x{} {}) initialized", .{
|
|
bootboot.bootboot.fb_width,
|
|
bootboot.bootboot.fb_height,
|
|
@tagName(bootboot.framebuffer_pixel_type() catch unreachable),
|
|
});
|
|
log(.Debug, "Logging initialized", .{});
|
|
|
|
// Initrd
|
|
|
|
global.initrd = @intToPtr([*]const u8, bootboot.bootboot.initrd_ptr)[0..bootboot.bootboot.initrd_size];
|
|
|
|
// Establish CPU capabilities
|
|
|
|
global.cpu_capabilities.initialize();
|
|
|
|
// Initialize memory management
|
|
|
|
log(.Debug, "Initializing memory management", .{});
|
|
|
|
const mmap = bootboot.memory_map();
|
|
const page_table = paging.PageMapLevel4.fromCr3(cpu.register.cr3());
|
|
const kernel_dynamic_data_address = 0 -% std.math.pow(usize, 2, global.cpu_capabilities.virtual_address_width - 1);
|
|
|
|
global.physical_memory = memory.PhysicalMemory.init(mmap);
|
|
global.kernel_memory = memory.VirtualMemory.init(page_table, kernel_dynamic_data_address);
|
|
|
|
paging.initialize(page_table);
|
|
|
|
// Initialize panic memory
|
|
|
|
panic_mod.initialize();
|
|
|
|
// Setup complete, allow AP's to continue
|
|
ap_lock.release();
|
|
|
|
// Call main kernel function
|
|
global.bp_stack = global.kernel_memory.?.alloc(.{ .writeable = true }, kernel_stack_size, std.Target.stack_align) catch @panic("Unable to allocate kernel stack");
|
|
const new_stack_address = @ptrToInt(&global.bp_stack.?[0]) + kernel_stack_size;
|
|
|
|
asm volatile (
|
|
\\movq %[addr], %%rsp
|
|
\\movq %%rsp, %%rbp
|
|
:
|
|
: [addr] "r" (new_stack_address)
|
|
: "memory"
|
|
);
|
|
@call(.{ .modifier = .never_inline }, kernel.main, .{});
|
|
}
|
|
|
|
fn init_ap() noreturn {
|
|
ap_lock.wait();
|
|
@call(.{ .modifier = .never_inline }, kernel.main_ap, .{});
|
|
}
|
|
|
|
export fn _start() noreturn {
|
|
assert(std.mem.eql(u8, &bootboot.bootboot.magic, "BOOT"));
|
|
|
|
@atomicStore(u8, &ap_lock.lock, 1, .SeqCst);
|
|
if (!apic.bootstrapCpuCore()) {
|
|
@call(.{ .modifier = .never_inline }, init_ap, .{});
|
|
}
|
|
|
|
@call(.{ .stack = &init_stack, .modifier = .never_inline }, init, .{});
|
|
}
|
|
|
|
comptime {
|
|
assert(builtin.arch == .x86_64);
|
|
}
|