Microkernel thing OS experiment (Zig ⚡)
1const std = @import("std");
2const build_helpers = @import("build_helpers");
3
4pub fn build(b: *std.Build) void {
5 const arch = b.option(build_helpers.Architecture, "arch", "The target architecture") orelse .amd64;
6
7 const ukernel_dep = b.dependency("ukernel", .{
8 .arch = arch,
9 });
10 const ukernel_artifact = ukernel_dep.artifact("ukernel");
11 const ukernel_inst = b.addInstallFile(ukernel_artifact.getEmittedBin(), arch.kernelExeName());
12 b.getInstallStep().dependOn(&ukernel_inst.step);
13
14 const root_dep = b.dependency("root_server", .{
15 .arch = arch,
16 });
17 const root_artifact = root_dep.artifact("root_server");
18 const root_inst = b.addInstallFile(root_artifact.getEmittedBin(), arch.rootTaskName());
19 b.getInstallStep().dependOn(&root_inst.step);
20
21 // Run in QEMU
22 run_blk: {
23 // Step 1: Install edk2 files to zig-out
24 const ovmf_code, const ovmf_vars = blk: {
25 const ovmf_dep = b.lazyDependency("edk2_binary", .{}) orelse break :run_blk;
26 break :blk .{
27 ovmf_dep.path("bin/RELEASEX64_OVMF_CODE.fd"),
28 ovmf_dep.path("bin/RELEASEX64_OVMF_VARS.fd"),
29 };
30 };
31
32 const loader_path = blk: {
33 const limine_dep = b.lazyDependency("limine_binary", .{}) orelse break :run_blk;
34 break :blk limine_dep.path("BOOTX64.EFI");
35 };
36
37 // Install Required dependencies
38 const code_install = b.addInstallFile(ovmf_code, "OVMF_CODE_X64.fd");
39 const vars_install = b.addInstallFile(ovmf_vars, "OVMF_VARS_X64.fd");
40 const loader_install = b.addInstallFileWithDir(loader_path, .{ .custom = "EFI/BOOT" }, "BOOTX64.EFI");
41 const config_install = b.addInstallFileWithDir(b.path("assets/limine.conf"), .{ .custom = "limine" }, "limine.conf");
42
43 const qemu_cmd = b.addSystemCommand(&.{ "qemu-system-x86_64", "-smp", "4", "-m", "4G", "-monitor", "stdio", "-drive", "format=raw,file=fat:rw:zig-out", "-drive", "if=pflash,format=raw,readonly=on,file=zig-out/OVMF_CODE_X64.fd", "-drive", "if=pflash,format=raw,file=zig-out/OVMF_VARS_X64.fd" });
44
45 // Depend on the install step (ukernel and root task)
46 qemu_cmd.step.dependOn(b.getInstallStep());
47 // Depend on OVMF code+vars, Limine bootloader, and Limine cfg
48 qemu_cmd.step.dependOn(&code_install.step);
49 qemu_cmd.step.dependOn(&vars_install.step);
50 qemu_cmd.step.dependOn(&loader_install.step);
51 qemu_cmd.step.dependOn(&config_install.step);
52
53 // Create the actual public callable step and depend on our command
54 const qemu_step = b.step("qemu", "Run in QEMU");
55 qemu_step.dependOn(&qemu_cmd.step);
56 }
57}