Microkernel thing OS experiment (Zig ⚡)
1const limine = @import("limine"); 2const std = @import("std"); 3const arch = @import("root.zig"); 4const common = @import("common"); 5const log = std.log.scoped(.aarch64_init); 6 7pub const limine_requests = struct { 8 // export var start_marker: limine.RequestsStartMarker linksection(".limine_reqs_start") = .{}; 9 // export var end_marker: limine.RequestsEndMarker linksection(".limine_reqs_end") = .{}; 10 11 pub export var base_revision: limine.BaseRevision = .{ .revision = 3 }; 12 pub export var framebuffer: limine.FramebufferRequest = .{}; 13 pub export var hhdm: limine.HhdmRequest = .{}; 14 pub export var memmap: limine.MemoryMapRequest = .{}; 15 pub export var rsdp_req: limine.RsdpRequest = .{}; 16 pub export var dtb_req: limine.DtbRequest = .{}; 17 pub export var modules: limine.ModuleRequest = .{}; 18 pub export var mp: limine.SmpMpFeature.MpRequest = .{}; 19}; 20 21pub fn bsp_init() callconv(.c) noreturn { 22 if (limine_requests.framebuffer.response) |fb_response| { 23 if (fb_response.framebuffer_count > 0) { 24 const fb = common.aux.Framebuffer.from_limine(fb_response.getFramebuffers()[0]); 25 common.init_data.framebuffer = fb; 26 @memset(fb.address[0..64], 0xFF); 27 } 28 } 29 arch.instructions.die(); 30 // Don't optimize away the limine requests 31 inline for (@typeInfo(limine_requests).@"struct".decls) |decl| { 32 std.mem.doNotOptimizeAway(&@field(limine_requests, decl.name)); 33 } 34 35 // If the base revision isn't supported, we can't boot 36 if (!limine_requests.base_revision.isSupported()) { 37 @branchHint(.cold); 38 arch.instructions.die(); 39 } 40 41 // Die if we don't have a memory map or Higher Half Direct Mapping 42 if (limine_requests.memmap.response == null) { 43 @branchHint(.cold); 44 arch.instructions.die(); 45 } 46 47 if (limine_requests.hhdm.response == null) { 48 @branchHint(.cold); 49 arch.instructions.die(); 50 } 51 const hhdm_offset = limine_requests.hhdm.response.?.offset; 52 common.init_data.hhdm_slide = hhdm_offset; 53 54 // Add in a framebuffer if found 55 initConsole(); 56 57 // Add in ACPI/dtb if found 58 initHwDesc(); 59 60 // Set up the temporary Physical Memory Allocator 61 common.mm.bootmem.init(); 62 63 // Attach the root task 64 if (limine_requests.modules.response) |module_response| { 65 if (module_response.module_count > 0) { 66 const mod = module_response.modules.?[0]; 67 const mod_addr: [*]align(4096) u8 = @ptrCast(mod.address); 68 const mod_size = mod.size; 69 log.info("Loading root task with {s} @ {*}", .{ mod.path, mod.address }); 70 common.init_data.root_task = mod_addr[0..mod_size]; 71 } 72 } else { 73 @branchHint(.unlikely); 74 @panic("No root task found!"); 75 } 76 77 log.info("Nothing else to do!", .{}); 78 79 arch.instructions.die(); 80} 81 82fn initConsole() void { 83 if (limine_requests.framebuffer.response) |fb_response| { 84 if (fb_response.framebuffer_count > 0) { 85 const fb = common.aux.Framebuffer.from_limine(fb_response.getFramebuffers()[0]); 86 common.init_data.framebuffer = fb; 87 // At this point, log becomes usable 88 common.init_data.console = console.Console.from_font(fb, console.DefaultFont); 89 } 90 } 91} 92 93fn initHwDesc() void { 94 if (limine_requests.dtb_req.response) |dtb_response| { 95 common.init_data.hardware_description = .{ .dtb = dtb_response.dtb_ptr }; 96 } 97 if (limine_requests.rsdp_req.response) |rsdp_response| { 98 common.init_data.hardware_description = .{ .acpi_rsdp = rsdp_response.address }; 99 } 100}