Microkernel thing OS experiment (Zig ⚡)
1const console = @import("console");
2const flanterm = @import("flanterm");
3const common = @import("../root.zig");
4const mm = common.mm;
5const std = @import("std");
6const arch = @import("arch");
7const spinlock = @import("spinlock");
8const limine = @import("limine");
9
10// Types
11pub const HardwareDescription = union(enum) {
12 /// Physical address of ACPI RSDP
13 acpi_rsdp: usize,
14 /// Virtual pointer to DTB
15 dtb: *anyopaque,
16 none,
17};
18
19pub const InitState = struct {
20 bootmem: mm.bootmem.BootPmm = .{},
21 console: ?flanterm.Context = null,
22 framebuffer: ?common.aux.Framebuffer = null,
23 hardware_description: HardwareDescription = .none,
24 root_task: []align(4096) u8 = undefined,
25 hhdm_slide: usize = 0,
26};
27
28pub const Framebuffer = struct {
29 const Self = @This();
30 address: [*]u32,
31 width: u64,
32 height: u64,
33 pitch: u64,
34 bypp: u16,
35 red_mask_size: u8,
36 red_mask_shift: u8,
37 green_mask_size: u8,
38 green_mask_shift: u8,
39 blue_mask_size: u8,
40 blue_mask_shift: u8,
41
42 pub fn from_limine(fb: *const limine.Framebuffer) Self {
43 return .{
44 .address = @ptrCast(@alignCast(fb.address)),
45 .width = fb.width,
46 .height = fb.height,
47 .pitch = fb.pitch,
48 .red_mask_size = fb.red_mask_size,
49 .red_mask_shift = fb.red_mask_shift,
50 .green_mask_size = fb.green_mask_size,
51 .green_mask_shift = fb.green_mask_shift,
52 .blue_mask_size = fb.blue_mask_size,
53 .blue_mask_shift = fb.blue_mask_shift,
54 .bypp = fb.bpp / 8,
55 };
56 }
57};
58
59var stdout_lock: spinlock.Spinlock = .{};
60
61pub fn logFn(
62 comptime message_level: std.log.Level,
63 comptime scope: @TypeOf(.enum_literal),
64 comptime format: []const u8,
65 args: anytype,
66) void {
67 if (common.init_data.console == null) return;
68
69 // Use the same naming as the default logger
70 const level, const color: flanterm.Colors.Color = switch (message_level) {
71 .debug => .{ "D", .green },
72 .err => .{ "E", .red },
73 .info => .{ "I", .cyan },
74 .warn => .{ "W", .yellow },
75 };
76 // Use same format as default once again
77 const scope_text = switch (scope) {
78 .default => "",
79 else => "<" ++ @tagName(scope) ++ ">",
80 };
81 const prefix = std.fmt.comptimePrint("{s}{s}: ", .{ level, scope_text });
82
83 {
84 const color_default: flanterm.Colors.Color = .default;
85 stdout_lock.lock();
86 defer stdout_lock.unlock();
87
88 var backing_buf = std.mem.zeroes([512]u8);
89 const buf = std.fmt.bufPrint(backing_buf[0..], color.esc_seq() ++ prefix ++ format ++ color_default.esc_seq() ++ "\n", args) catch return;
90
91 common.init_data.console.?.write_slice(buf);
92 // cons.setColor(color, 0);
93 // cons.writer().print(prefix ++ format ++ "\n", args) catch return;
94 }
95}
96
97pub fn panic(msg: []const u8, first_trace_addr: ?usize) noreturn {
98 _ = first_trace_addr;
99 const log = std.log.scoped(.panic);
100 log.err("PANIC: {s}", .{msg});
101 var it = std.debug.StackIterator.init(@returnAddress(), @frameAddress());
102 defer it.deinit();
103 while (it.next()) |addr| {
104 if (addr == 0) break;
105 log.err("Addr: 0x{x:0>16}", .{addr});
106 }
107 arch.instructions.die();
108}