Skip to content

Commit

Permalink
Make bootloader and tools able to be built independent of one another
Browse files Browse the repository at this point in the history
  • Loading branch information
jmbaur committed Jun 16, 2024
1 parent 4fe2acb commit 7484603
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 186 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ jobs:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- name: Native build for x86_64-linux
run: nix build --print-build-logs .\#tinyboot
- name: Cross build for aarch64-linux
run: nix build --print-build-logs .\#pkgsCross.aarch64-multiplatform.tinyboot
run: nix build --print-build-logs .\#tinybootLoader .\#tinybootTools
- name: Cross build loader for aarch64-linux
run: nix build --print-build-logs .\#pkgsCross.aarch64-multiplatform.tinybootLoader
- name: Check nix flake
run: nix flake check --print-build-logs
227 changes: 116 additions & 111 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,111 +11,140 @@ pub fn build(b: *std.Build) !void {
},
);
const optimize = b.standardOptimizeOption(.{});
const tboot_loader_optimize = if (optimize == std.builtin.OptimizeMode.Debug)
std.builtin.OptimizeMode.Debug
else
// Always use release small, smallest size is our goal.
std.builtin.OptimizeMode.ReleaseSmall;

const with_loader = b.option(bool, "loader", "With boot loader") orelse true;
const with_tools = b.option(bool, "tools", "With tools") orelse true;

const loglevel = b.option(
u8,
"loglevel",
"Log level",
) orelse @intFromEnum(std.log.Level.debug);

const tboot_loader_options = b.addOptions();
tboot_loader_options.addOption(u8, "loglevel", loglevel);

const tboot_loader_optimize = if (optimize == std.builtin.OptimizeMode.Debug)
std.builtin.OptimizeMode.Debug
else
// Always use release small, smallest size is our goal.
std.builtin.OptimizeMode.ReleaseSmall;
const clap = b.dependency("clap", .{});

const linux_headers_translated = b.addTranslateC(.{
.root_source_file = .{ .path = "src/linux.h" },
.target = target,
// TODO(jared): how much does optimization do for the translate-c stuff?
.optimize = tboot_loader_optimize,
});

const linux_headers_module = linux_headers_translated.addModule("linux_headers");

const clap = b.dependency("clap", .{});
const tboot_loader_options = b.addOptions();
tboot_loader_options.addOption(u8, "loglevel", loglevel);

const tboot_loader = b.addExecutable(.{
.name = "tboot-loader",
.root_source_file = .{ .path = "src/tboot-loader.zig" },
.target = target,
.optimize = tboot_loader_optimize,
.strip = optimize != std.builtin.OptimizeMode.Debug,
});
tboot_loader.root_module.addOptions("build_options", tboot_loader_options);
tboot_loader.root_module.addImport("linux_headers", linux_headers_module);
if (with_loader) {
const tboot_loader = b.addExecutable(.{
.name = "tboot-loader",
.root_source_file = .{ .path = "src/tboot-loader.zig" },
.target = target,
.optimize = tboot_loader_optimize,
.strip = optimize != std.builtin.OptimizeMode.Debug,
});
tboot_loader.root_module.addOptions("build_options", tboot_loader_options);
tboot_loader.root_module.addImport("linux_headers", linux_headers_module);

const cpio_tool = b.addRunArtifact(b.addExecutable(.{
.name = "cpio",
.target = b.host,
.root_source_file = .{ .path = "src/cpio/main.zig" },
}));
cpio_tool.addArtifactArg(tboot_loader);
const cpio_archive = b.addInstallFile(
cpio_tool.addOutputFileArg("tboot-loader.cpio"),
"tboot-loader.cpio",
);

// install the cpio archive during "zig build install"
b.getInstallStep().dependOn(&cpio_archive.step);

const runner_tool = b.addRunArtifact(b.addExecutable(.{
.name = "tboot-runner",
.target = b.host,
.root_source_file = .{ .path = "src/runner.zig" },
}));
runner_tool.step.dependOn(&cpio_archive.step);
runner_tool.addArg(b.makeTempPath());
runner_tool.addFileArg(cpio_archive.source);

var env = try std.process.getEnvMap(b.allocator);
defer env.deinit();

if (env.get("TINYBOOT_KERNEL")) |kernel| {
runner_tool.addArg(kernel);
}

// extra args passed through to qemu
if (b.args) |args| {
runner_tool.addArgs(args);
}

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

if (with_tools) {
const tboot_bless_boot = b.addExecutable(.{
.name = "tboot-bless-boot",
.root_source_file = .{ .path = "src/tboot-bless-boot.zig" },
.target = target,
.optimize = optimize,
.strip = optimize != std.builtin.OptimizeMode.Debug,
});
b.installArtifact(tboot_bless_boot);

const tboot_bless_boot_generator = b.addExecutable(.{
.name = "tboot-bless-boot-generator",
.root_source_file = .{ .path = "src/tboot-bless-boot-generator.zig" },
.target = target,
.optimize = optimize,
.strip = optimize != std.builtin.OptimizeMode.Debug,
});
b.installArtifact(tboot_bless_boot_generator);

const tboot_sign = b.addExecutable(.{
.name = "tboot-sign",
.root_source_file = .{ .path = "src/tboot-sign.zig" },
.target = target,
.optimize = optimize,
.strip = optimize != std.builtin.OptimizeMode.Debug,
});
tboot_sign.linkLibC();
tboot_sign.linkSystemLibrary("libcrypto");
tboot_sign.root_module.addImport("clap", clap.module("clap"));
b.installArtifact(tboot_sign);

const tboot_nixos_install = b.addExecutable(.{
.name = "tboot-nixos-install",
.root_source_file = .{ .path = "src/tboot-nixos-install.zig" },
.target = target,
.optimize = optimize,
.strip = optimize != std.builtin.OptimizeMode.Debug,
});
tboot_nixos_install.linkLibC();
tboot_nixos_install.linkSystemLibrary("libcrypto");
tboot_nixos_install.root_module.addImport("clap", clap.module("clap"));
b.installArtifact(tboot_nixos_install);

const modem_tool = b.addExecutable(.{
.name = "xmodem",
.root_source_file = .{ .path = "src/xmodem.zig" },
.target = target,
.optimize = optimize,
.strip = optimize != std.builtin.OptimizeMode.Debug,
});
modem_tool.root_module.addImport("linux_headers", linux_headers_module);
modem_tool.root_module.addImport("clap", clap.module("clap"));
b.installArtifact(modem_tool);
}
// make the default step just compile tboot-loader
b.default_step = &tboot_loader.step;

const cpio_tool = b.addRunArtifact(b.addExecutable(.{
.name = "cpio",
.target = b.host,
.root_source_file = .{ .path = "src/cpio/main.zig" },
}));
cpio_tool.addArtifactArg(tboot_loader);
const cpio_archive = b.addInstallFile(
cpio_tool.addOutputFileArg("tboot-loader.cpio"),
"tboot-loader.cpio",
);

// install the cpio archive during "zig build install"
b.getInstallStep().dependOn(&cpio_archive.step);

const tboot_bless_boot = b.addExecutable(.{
.name = "tboot-bless-boot",
.root_source_file = .{ .path = "src/tboot-bless-boot.zig" },
.target = target,
.optimize = optimize,
.strip = optimize != std.builtin.OptimizeMode.Debug,
});
b.installArtifact(tboot_bless_boot);

const tboot_bless_boot_generator = b.addExecutable(.{
.name = "tboot-bless-boot-generator",
.root_source_file = .{ .path = "src/tboot-bless-boot-generator.zig" },
.target = target,
.optimize = optimize,
.strip = optimize != std.builtin.OptimizeMode.Debug,
});
b.installArtifact(tboot_bless_boot_generator);

const tboot_sign = b.addExecutable(.{
.name = "tboot-sign",
.root_source_file = .{ .path = "src/tboot-sign.zig" },
.target = target,
.optimize = optimize,
.strip = optimize != std.builtin.OptimizeMode.Debug,
});
tboot_sign.linkLibC();
tboot_sign.linkSystemLibrary("libcrypto");
tboot_sign.root_module.addImport("clap", clap.module("clap"));
b.installArtifact(tboot_sign);

const tboot_nixos_install = b.addExecutable(.{
.name = "tboot-nixos-install",
.root_source_file = .{ .path = "src/tboot-nixos-install.zig" },
.target = target,
.optimize = optimize,
.strip = optimize != std.builtin.OptimizeMode.Debug,
});
tboot_nixos_install.linkLibC();
tboot_nixos_install.linkSystemLibrary("libcrypto");
tboot_nixos_install.root_module.addImport("clap", clap.module("clap"));
b.installArtifact(tboot_nixos_install);

const modem_tool = b.addExecutable(.{
.name = "xmodem",
.root_source_file = .{ .path = "src/xmodem.zig" },
.target = target,
.optimize = optimize,
.strip = optimize != std.builtin.OptimizeMode.Debug,
});
modem_tool.root_module.addImport("linux_headers", linux_headers_module);
modem_tool.root_module.addImport("clap", clap.module("clap"));
b.installArtifact(modem_tool);
// b.default_step = &tboot_loader.step;

const unit_tests = b.addTest(.{
.root_source_file = .{ .path = "src/test.zig" },
Expand All @@ -127,28 +156,4 @@ pub fn build(b: *std.Build) !void {
unit_tests.root_module.addImport("linux_headers", linux_headers_module);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&b.addRunArtifact(unit_tests).step);

const runner_tool = b.addRunArtifact(b.addExecutable(.{
.name = "tboot-runner",
.target = b.host,
.root_source_file = .{ .path = "src/runner.zig" },
}));
runner_tool.step.dependOn(&cpio_archive.step);
runner_tool.addArg(b.makeTempPath());
runner_tool.addFileArg(cpio_archive.source);

var env = try std.process.getEnvMap(b.allocator);
defer env.deinit();

if (env.get("TINYBOOT_KERNEL")) |kernel| {
runner_tool.addArg(kernel);
}

// extra args passed through to qemu
if (b.args) |args| {
runner_tool.addArgs(args);
}

const run_step = b.step("run", "Run in qemu");
run_step.dependOn(&runner_tool.step);
}
28 changes: 5 additions & 23 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 10 additions & 6 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
inputs = {
coreboot.flake = false;
coreboot.url = "git+https://github.com/coreboot/coreboot?ref=refs/tags/24.05&submodules=1";
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
zig.flake = false;
zig.url = "github:ziglang/zig/0.12.x";
nixpkgs.url = "github:nixos/nixpkgs/master";
};
outputs = inputs: {
formatter = inputs.nixpkgs.lib.mapAttrs (_: pkgs: pkgs.nixfmt-rfc-style) inputs.self.legacyPackages;
Expand All @@ -21,8 +19,14 @@
corebootSrc = inputs.coreboot.outPath;
version = "24.05";
};
# TODO(jared): use pkgsStatic for now since zig's cross-compilation dynamic linking support seems to be broken
tinyboot = prev.pkgsStatic.callPackage ./pkgs/tinyboot { zigInput = inputs.zig; };
tinybootLoader = prev.callPackage ./pkgs/tinyboot {
withLoader = true;
withTools = false;
};
tinybootTools = prev.callPackage ./pkgs/tinyboot {
withLoader = false;
withTools = true;
};
armTrustedFirmwareMT8183 = prev.callPackage ./pkgs/arm-trusted-firmware-cros {
platform = "mt8183";
};
Expand Down Expand Up @@ -60,7 +64,7 @@
);
devShells = inputs.nixpkgs.lib.mapAttrs (_: pkgs: {
default = pkgs.mkShell {
inputsFrom = [ pkgs.tinyboot ];
inputsFrom = [ pkgs.tinybootLoader ];
packages = with pkgs; [
swtpm
qemu
Expand Down
6 changes: 3 additions & 3 deletions nixos-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,15 @@ in
boot.loader.external = lib.mkIf (with config.system.switch; enable || enableNg) {
enable = true;
installHook = toString [
(lib.getExe' pkgs.tinyboot "tboot-nixos-install")
(lib.getExe' pkgs.tinybootTools "tboot-nixos-install")
"--esp-mnt=${config.boot.loader.efi.efiSysMountPoint}"
"--private-key=${cfg.verifiedBoot.tbootPrivateKey}"
"--public-key=${cfg.verifiedBoot.tbootPublicCertificate}"
"--timeout=${toString config.boot.loader.timeout}"
"--max-tries=${toString cfg.maxFailedBootAttempts}"
];
};
systemd.generators.tboot-bless-boot-generator = lib.getExe' pkgs.tinyboot "tboot-bless-boot-generator";
systemd.generators.tboot-bless-boot-generator = lib.getExe' pkgs.tinybootTools "tboot-bless-boot-generator";
systemd.services.tboot-bless-boot = {
description = "Mark the Current Boot Loader Entry as Good";
documentation = [ "https://github.com/jmbaur/tinyboot" ];
Expand All @@ -91,7 +91,7 @@ in
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = "${lib.getExe' pkgs.tinyboot "tboot-bless-boot"} ${config.boot.loader.efi.efiSysMountPoint} good";
ExecStart = "${lib.getExe' pkgs.tinybootTools "tboot-bless-boot"} ${config.boot.loader.efi.efiSysMountPoint} good";
};
};
}
Expand Down
2 changes: 1 addition & 1 deletion options.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
}:
let
boardsDir = builtins.readDir ./boards;
tinyboot = pkgs.tinyboot.override { inherit (config) debug; };
tinyboot = pkgs.tinybootLoader.override { inherit (config) debug; };
testStartupScript = pkgs.writeScript "installer-startup-script" ''
#!/bin/sh
mkdir -p /proc && mount -t proc proc /proc
Expand Down
Loading

0 comments on commit 7484603

Please sign in to comment.