Microkernel thing OS experiment (Zig ⚡)
1const console = @import("console");
2const common = @import("root.zig");
3const mm = common.mm;
4const std = @import("std");
5const arch = @import("arch");
6const spinlock = @import("spinlock");
7
8// Types
9pub const HardwareDescription = union(enum) {
10 /// Physical address of ACPI RSDP
11 acpi_rsdp: usize,
12 /// Virtual pointer to DTB
13 dtb: *anyopaque,
14 none,
15};
16
17pub const InitState = struct {
18 bootmem: mm.bootmem.BootPmm = .{},
19 console: ?console.Console = null,
20 framebuffer: ?console.Framebuffer = null,
21 hardware_description: HardwareDescription = .none,
22 root_task_elf: []align(4096) u8 = undefined,
23 hhdm_slide: usize = 0,
24 kernel_paging_ctx: arch.mm.paging.Context = undefined,
25};
26
27pub fn initConsole() void {
28 const fb = common.init_data.framebuffer.?;
29 // Create a canvas for the console to render to
30 const canvas: [*]u8 = @ptrFromInt(common.init_data.bootmem.allocMem(fb.width * fb.height * fb.bypp) catch @panic("Couldn't allocate a canvas"));
31 @memset(canvas[0 .. fb.width * fb.height * fb.bypp], 0);
32
33 // Set the console instance
34 common.init_data.console = console.Console.init(fb, canvas);
35}
36
37var stdout_lock: spinlock.Spinlock = .{};
38
39pub fn logFn(
40 comptime message_level: std.log.Level,
41 comptime scope: @TypeOf(.enum_literal),
42 comptime format: []const u8,
43 args: anytype,
44) void {
45 if (common.init_data.console == null) return;
46
47 // Use the same naming as the default logger
48 const level, const color: u32 = switch (message_level) {
49 .debug => .{ "D", 0x3bcf1d },
50 .err => .{ "E", 0xff0000 },
51 .info => .{ "I", 0x00bbbb },
52 .warn => .{ "W", 0xfee409 },
53 };
54 // Use same format as default once again
55 const scope_text = switch (scope) {
56 .default => "",
57 else => "<" ++ @tagName(scope) ++ ">",
58 };
59 const prefix = std.fmt.comptimePrint("{s}{s}: ", .{ level, scope_text });
60
61 {
62 stdout_lock.lock();
63 defer stdout_lock.unlock();
64
65 common.init_data.console.?.setColor(color, 0);
66 // No buffering for now
67 var writer = console.Console.Writer.init(&common.init_data.console.?, &.{});
68 writer.interface.print(prefix ++ format ++ "\n", args) catch return;
69 }
70}
71
72pub fn panic(msg: []const u8, first_trace_addr: ?usize) noreturn {
73 _ = first_trace_addr;
74 const log = std.log.scoped(.panic);
75 log.err("PANIC: {s}", .{msg});
76 var it = std.debug.StackIterator.init(@returnAddress(), @frameAddress());
77 defer it.deinit();
78 while (it.next()) |addr| {
79 if (addr == 0) break;
80 log.err("Addr: 0x{x:0>16}", .{addr});
81 }
82 arch.instructions.die();
83}