From 2c30620ed256d1754b0e6f5873cfaf0f5228f2b9 Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Mon, 3 Jul 2023 23:47:26 -0700 Subject: [PATCH] coreboot: separate compilation from payload installation This commit causes the coreboot payload (i.e. the Linux kernel, initramfs, and any necessary DTBs) to be inserted into the coreboot image as part of a separate derivation from the one which compiles coreboot. As a result, changing the contents of the initramfs is extremely fast -- it can now be done without any recompilation. As a result of this, the attribute name for the final image to be flashed has changed from `coreboot` to `image`. The `coreboot` attribute now builds a payloadless `coreboot.rom`. --- src/coreboot/default.nix | 8 +--- src/default.nix | 5 ++- src/image/default.nix | 63 ++++++++++++++++++++++++++++++ src/main/default.nix | 8 ++-- src/platform/am1i/default.nix | 9 ++--- src/platform/common/amd64.nix | 8 ++-- src/platform/common/arm64.nix | 2 +- src/platform/kevin/default.nix | 12 +++--- src/platform/kevin/fit/default.nix | 20 +++++++++- src/platform/kgpe/default.nix | 13 +++--- 10 files changed, 112 insertions(+), 36 deletions(-) create mode 100644 src/image/default.nix diff --git a/src/coreboot/default.nix b/src/coreboot/default.nix index eb417d7..21e0159 100644 --- a/src/coreboot/default.nix +++ b/src/coreboot/default.nix @@ -2,10 +2,8 @@ , nixpkgsOnBuildForBuild , nixpkgsOnBuildForHost , coreboot-toolchain ? throw "missing" -, payload ? throw "you must provide a coreboot payload (Linux kernel image or FIT)" , fmap ? throw "you must provide an FMAP (flash chip partition table)" , config ? throw "you must provide a -style structuredConfig" -, initramfs_image # path to the initramfs `cpio` archive , iasl ? null # a specific iasl to use, if needed , console_loglevel ? "6" # 8=SPEW, 7=DEBUG, 6=INFO @@ -13,7 +11,6 @@ # these integers to ttyS* values is occasionally not the identity # map. , uart-for-console ? throw "you must provide uart-for-console" -, linux-command-line }: let @@ -152,10 +149,7 @@ stdenv.mkDerivation { "DEFAULT_CONSOLE_LOGLEVEL_${toString console_loglevel}" = lib.mkForce yes; DEFAULT_CONSOLE_LOGLEVEL = lib.mkForce (freeform (toString console_loglevel)); FMDFILE = lib.mkForce (freeform "${fmap}"); - PAYLOAD_FILE = lib.mkForce (freeform "${payload}"); - LINUX_COMMAND_LINE = lib.mkForce (freeform "${linux-command-line}"); - } // lib.optionalAttrs (initramfs_image != null) { - LINUX_INITRD = lib.mkForce (freeform "${initramfs_image}"); + PAYLOAD_NONE = lib.mkForce yes; } // lib.optionalAttrs (uart-for-console != null) { UART_FOR_CONSOLE = lib.mkForce (freeform "${builtins.toString uart-for-console}"); } // lib.optionalAttrs (iasl != null) { diff --git a/src/default.nix b/src/default.nix index 1c78ed1..133e0f6 100644 --- a/src/default.nix +++ b/src/default.nix @@ -26,7 +26,8 @@ let in "console=${console} earlyprintk=${console}"; iasl_20180531 = final.nixpkgsOnBuildForBuild.callPackage ./coreboot/iasl_20180531 { }; - coreboot = final.callPackage ./coreboot { + coreboot = final.callPackage ./coreboot { }; + image = final.callPackage ./image { initramfs_image = final.initramfs; }; kernel = final.callPackage ./kernel { }; @@ -49,7 +50,7 @@ let # totally different platform than the Device Under Test. # TODO(amjoseph): don't hardwire the chip type here '' - em100 -v --stop --holdpin float -c GD25Q128C --download ${final.coreboot}/coreboot.rom --start --trace + em100 -v --stop --holdpin float -c GD25Q128C --download ${final.image}/coreboot.rom --start --trace ''; # # TODO(amjoseph): add a sanity check that (a) the image being diff --git a/src/image/default.nix b/src/image/default.nix new file mode 100644 index 0000000..9bc65cd --- /dev/null +++ b/src/image/default.nix @@ -0,0 +1,63 @@ +{ lib +, nixpkgsOnBuildForBuild +, nixpkgsOnBuildForHost +, coreboot-toolchain ? throw "missing" +, coreboot ? throw "missing" +, payload ? throw "you must provide a coreboot payload (Linux kernel image or FIT)" +, payload-compression-type ? "none" +, payload-prefix ? "prefix" +, payload-name ? "payload" +, initramfs_image # path to the initramfs `cpio` archive +, linux-command-line ? null +}: + +nixpkgsOnBuildForHost.stdenv.mkDerivation { + pname = "ownerboot"; + inherit (coreboot) version; + + passthru = { inherit (coreboot) src fmap; }; + + nativeBuildInputs = [ + nixpkgsOnBuildForBuild.coreboot-utils + ]; + + dontUnpack = true; + + buildPhase = let + update-cbfs = region: lib.concatStringsSep " " ([ + "cbfstool" + "coreboot.rom" + "add-payload" + "-r${region}" + "-f${payload}" + "-n${payload-prefix}/${payload-name}" + "-c${payload-compression-type}" + ] ++ lib.optionals (linux-command-line != null) [ + "-C'${linux-command-line}'" + ] ++ lib.optionals (initramfs_image != null) [ + "-I'${initramfs_image}'" + ] ++ [ + "\n" + ]); + in '' + runHook preBuild + cp ${coreboot}/coreboot.rom . + chmod +w coreboot.rom + cbfstool coreboot.rom print -rNORMAL + ${lib.concatMapStrings (region: update-cbfs region) [ "NORMAL" "FALLBACK" ]} + runHook postBuild + ''; + + installPhase = '' + runHook preBuild + mkdir -p $out + cp -a ${coreboot}/* $out/ + chmod +w $out/coreboot.rom + rm $out/coreboot.rom + mv coreboot.rom $out/ + runHook postBuild + ''; + + dontFixup = true; + +} diff --git a/src/main/default.nix b/src/main/default.nix index aec8d88..d9ade98 100644 --- a/src/main/default.nix +++ b/src/main/default.nix @@ -2,7 +2,7 @@ { nixpkgsOnBuildForHost , nixpkgsOnBuildForBuild , lib -, coreboot +, image , scripts }: @@ -21,9 +21,9 @@ in nixpkgsOnBuildForHost.stdenv.mkDerivation (finalAttrs: { runHook preInstall mkdir -p $out/{etc,bin} - ln -s ${coreboot}/coreboot.rom $out/ - ln -s ${coreboot}/config $out/etc/coreboot.config - ln -s ${coreboot.passthru.fmap} $out/etc/coreboot.fmap + ln -s ${image}/coreboot.rom $out/ + ln -s ${image}/config $out/etc/coreboot.config + ln -s ${image.passthru.fmap} $out/etc/coreboot.fmap '' + (lib.concatStringsSep "\n" (lib.mapAttrsToList (scriptName: scriptText: '' ln -s ${writeShellScript scriptName scriptText} $out/bin/${scriptName}.sh diff --git a/src/platform/am1i/default.nix b/src/platform/am1i/default.nix index b17d6eb..cd1653b 100644 --- a/src/platform/am1i/default.nix +++ b/src/platform/am1i/default.nix @@ -19,9 +19,12 @@ console-device = "ttyS1"; + image = prev.image.override { + payload = "${final.kernel}/bzImage"; + }; + coreboot = (prev.coreboot.override { iasl = final.iasl_20180531; - payload = "${final.kernel}/bzImage"; coreboot-toolchain = with final.coreboot-toolchain; [ x64 i386 ]; fmap = ./custom.fmap; config = with lib.kernel; { @@ -36,10 +39,6 @@ CBFS_SIZE = lib.mkForce (freeform "0x7FFAC8"); - PAYLOAD_LINUX = lib.mkForce yes; - PAYLOAD_OPTIONS = lib.mkForce (freeform ""); - COMPRESS_SECONDARY_PAYLOAD = lib.mkForce yes; - CONSOLE_CBMEM = lib.mkForce no; DRIVERS_INTEL_WIFI = lib.mkForce no; HUDSON_XHCI_ENABLE = lib.mkForce no; diff --git a/src/platform/common/amd64.nix b/src/platform/common/amd64.nix index ec592e0..cb6f981 100644 --- a/src/platform/common/amd64.nix +++ b/src/platform/common/amd64.nix @@ -31,10 +31,10 @@ ${final.flashrom}/bin/flashrom -p internal $@ ${moreFlags} ''; flashromWriteScript = moreFlags: - flashromScript "-w ${final.coreboot}/coreboot.rom ${moreFlags}"; + flashromScript "-w ${final.image}/coreboot.rom ${moreFlags}"; nvramToolScript = moreFlags: '' set -euo pipefail - ${final.nixpkgsOnBuildForHost.nvramtool}/bin/nvramtool -y ${final.coreboot}/cmos.layout ${moreFlags} + ${final.nixpkgsOnBuildForHost.nvramtool}/bin/nvramtool -y ${final.image}/cmos.layout ${moreFlags} ''; in prev.scripts // { flashrom = flashromScript "$@"; @@ -51,7 +51,7 @@ nvram-tool = nvramToolScript "$@"; nvram-all-read = nvramToolScript "-a"; nvram-all-write = nvramToolScript "-p $1"; - nvram-all-defaults = nvramToolScript "-p ${final.coreboot}/cmos.default"; + nvram-all-defaults = nvramToolScript "-p ${final.image}/cmos.default"; nvram-bootcount-show = nvramToolScript "-n -r reboot_counter"; nvram-parameter-read = nvramToolScript "-n -r $1"; nvram-parameter-choices = nvramToolScript "-e $1"; @@ -62,7 +62,7 @@ main = prev.main.overrideAttrs(previousAttrs: { # cmos nvram is an x86-ism postInstall = (previousAttrs.postInstall or "") + '' - ln -s ${final.coreboot}/{cmos.layout,cmos.default} $out/etc/ + ln -s ${final.image}/{cmos.layout,cmos.default} $out/etc/ ''; }); })]; diff --git a/src/platform/common/arm64.nix b/src/platform/common/arm64.nix index 2f34cf1..8c5c33a 100644 --- a/src/platform/common/arm64.nix +++ b/src/platform/common/arm64.nix @@ -13,7 +13,7 @@ ${final.flashrom}/bin/flashrom -p linux_mtd ${moreFlags} ''; flashromWriteScript = moreFlags: - flashromScript "-w ${final.coreboot}/coreboot.rom ${moreFlags}"; + flashromScript "-w ${final.image}/coreboot.rom ${moreFlags}"; in prev.scripts // { flashrom = flashromScript "$@"; flash-write-fallback = flashromWriteScript "--fmap -i FALLBACK"; diff --git a/src/platform/kevin/default.nix b/src/platform/kevin/default.nix index bf21d57..8807986 100644 --- a/src/platform/kevin/default.nix +++ b/src/platform/kevin/default.nix @@ -73,12 +73,16 @@ in { }; fit = final.nixpkgsOnBuildForBuild.callPackage (import ./fit) { - inherit (final) initramfs kernel; + inherit (final) initramfs kernel linux-command-line; + }; + + image = prev.image.override { + payload = "${final.fit}/Image.fit"; + initramfs_image = null; # it is part of the FIT image }; coreboot = (prev.coreboot.override { - payload = "${final.fit}/Image.fit"; fmap = ./custom.fmap; config = with lib.kernel; { CBFS_PREFIX = lib.mkForce (freeform "prefix"); @@ -99,12 +103,11 @@ in { CONSOLE_SERIAL = lib.mkForce yes; #BOOTBLOCK_CONSOLE = lib.mkForce yes; + COMPRESS_SECONDARY_PAYLOAD = lib.mkForce no; TPM_DEACTIVATE = lib.mkForce yes; - PAYLOAD_FIT = lib.mkForce yes; PAYLOAD_FIT_SUPPORT = lib.mkForce yes; - COMPRESS_SECONDARY_PAYLOAD = lib.mkForce no; DEBUG_CBFS = lib.mkForce yes; # maybe enable this @@ -114,7 +117,6 @@ in { ARM64_BL31_EXTERNAL_FILE = lib.mkForce (freeform "${final.atf}/bl31.elf"); }; coreboot-toolchain = with final.coreboot-toolchain; [ aarch64 ]; - initramfs_image = null; # it is part of the FIT image uart-for-console = if final.console-device == "ttyS2" then 0 else if final.console-device == null then null diff --git a/src/platform/kevin/fit/default.nix b/src/platform/kevin/fit/default.nix index 874118e..266f80e 100644 --- a/src/platform/kevin/fit/default.nix +++ b/src/platform/kevin/fit/default.nix @@ -5,11 +5,29 @@ , ubootTools , kernel , initramfs +, linux-command-line }: let initramfs_lzma = runCommand "initramfs.lzma" { } '' lzma < ${initramfs} > $out; ''; + dtb-with-linux-command-line = stdenv.mkDerivation { + name = "rk3399-gru-kevin-with-linux-command-line.dtb"; + nativeBuildInputs = [ dtc ubootTools ]; + dontUnpack = true; + buildPhase = '' + runHook preBuild + cp ${kernel}/rk3399-gru-kevin.dtb . + chmod +w rk3399-gru-kevin.dtb + fdtput -t s -v -p rk3399-gru-kevin.dtb /chosen bootargs '${linux-command-line}' + runHook posBuild + ''; + installPhase = '' + runHook preInstall + mv rk3399-gru-kevin.dtb $out + runHook postInstall + ''; + }; in stdenv.mkDerivation { name = "ownerboot-stage1-fit"; dontUnpack = true; @@ -58,7 +76,7 @@ in stdenv.mkDerivation { }; fdt { description = "rk3399-gru-kevin.dtb"; - data = /incbin/("${kernel}/rk3399-gru-kevin.dtb"); + data = /incbin/("${dtb-with-linux-command-line}"); type = "flat_dt"; arch = "arm64"; compression = "none"; diff --git a/src/platform/kgpe/default.nix b/src/platform/kgpe/default.nix index c26b098..5b79565 100644 --- a/src/platform/kgpe/default.nix +++ b/src/platform/kgpe/default.nix @@ -20,8 +20,8 @@ userspace = prev.userspace.overrideAttrs (a: { postInstall = (a.postInstall or "") + '' mkdir -p $out/etc - cp ${final.coreboot.src}/src/mainboard/asus/kgpe-d16/cmos.layout $out/etc/ - cp ${final.coreboot.src}/src/mainboard/asus/kgpe-d16/cmos.default $out/etc/ + cp ${final.image.src}/src/mainboard/asus/kgpe-d16/cmos.layout $out/etc/ + cp ${final.image.src}/src/mainboard/asus/kgpe-d16/cmos.default $out/etc/ ''; }); @@ -43,9 +43,12 @@ # TODO: use a NixOS-style structuredConfig for this. cmos-default = null; + image = prev.image.override { + payload = "${final.kernel}/bzImage"; + }; + coreboot = (prev.coreboot.override { iasl = final.iasl_20180531; - payload = "${final.kernel}/bzImage"; fmap = ./custom.fmap; config = with lib.kernel; { CBFS_PREFIX = lib.mkForce (freeform "prefix"); @@ -84,10 +87,6 @@ NO_POST = lib.mkForce yes; - PAYLOAD_LINUX = lib.mkForce yes; - PAYLOAD_OPTIONS = lib.mkForce (freeform ""); - COMPRESS_SECONDARY_PAYLOAD = lib.mkForce yes; - CPU_MICROCODE_CBFS_GENERATE = lib.mkForce yes; CPU_MICROCODE_MULTIPLE_FILES = lib.mkForce yes; CPU_UCODE_BINARIES = lib.mkForce (freeform "");