λ

lumine

UEFI x86_64 bootloader for linux kernel images

settings

build.zig

2239 bytes raw

const std = @import("std");

const Arch = enum {
    x86_64,
    aarch64,

    pub fn stdlib(self: Arch) std.Target.Cpu.Arch {
        return switch (self) {
            .x86_64 => .x86_64,
            .aarch64 => .aarch64,
        };
    }

    pub fn efiName(self: Arch, b: *std.Build) []const u8 {
        const suffix = switch (self) {
            .x86_64 => "X64",
            .aarch64 => "AA64",
        };
        return b.fmt("BOOT{s}", .{suffix});
    }
};

pub fn build(b: *std.Build) void {
    const optimize = b.standardOptimizeOption(.{});

    const cpu_arch = b.option(Arch, "arch", "cpu architecture") orelse .x86_64;

    const efi_name = cpu_arch.efiName(b);

    const lumine_exe = b.addExecutable(.{
        .name = efi_name,
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = b.resolveTargetQuery(.{
                .os_tag = .uefi,
                .cpu_arch = cpu_arch.stdlib(),
            }),
            .optimize = optimize,
        }),
    });

    const install_step = b.getInstallStep();

    const lumine_install = b.addInstallArtifact(lumine_exe, .{});
    install_step.dependOn(&lumine_install.step);

    const qemu_exe = b.option([]const u8, "qemu", "path to qemu binary") orelse b.fmt("qemu-system-{t}", .{cpu_arch});
    const qemu_cmd = b.addSystemCommand(&.{ qemu_exe, "-m", "512M", "-serial", "mon:stdio", "-nographic", "-no-reboot", "-no-shutdown" });

    {
        const ovmf_dep = b.dependency("ovmf", .{});
        const ovmf_code = ovmf_dep.path(b.fmt("ovmf-code-{t}.fd", .{cpu_arch}));

        switch (cpu_arch) {
            .aarch64 => {
                qemu_cmd.addArgs(&.{ "-M", "virt", "-cpu", "max" });
            },
            .x86_64 => {},
        }

        qemu_cmd.addArg("-bios");
        qemu_cmd.addFileArg(ovmf_code);
    }

    {
        const boot_dir = b.addTempFiles();
        _ = boot_dir.addCopyFile(lumine_exe.getEmittedBin(), b.fmt("EFI/BOOT/{s}.EFI", .{efi_name}));

        qemu_cmd.addArg("-drive");
        qemu_cmd.addPrefixedDirectoryArg("format=raw,file=fat:rw:", boot_dir.getDirectory());
    }

    const run_step = b.step("run", "run in qemu");
    run_step.dependOn(&qemu_cmd.step);
}