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`.
master
Adam Joseph 1 year ago
parent 8efee177f2
commit 2c30620ed2

@ -2,10 +2,8 @@
, nixpkgsOnBuildForBuild , nixpkgsOnBuildForBuild
, nixpkgsOnBuildForHost , nixpkgsOnBuildForHost
, coreboot-toolchain ? throw "missing" , 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)" , fmap ? throw "you must provide an FMAP (flash chip partition table)"
, config ? throw "you must provide a <nixpkgs/lib/modules.nix>-style structuredConfig" , config ? throw "you must provide a <nixpkgs/lib/modules.nix>-style structuredConfig"
, initramfs_image # path to the initramfs `cpio` archive
, iasl ? null # a specific iasl to use, if needed , iasl ? null # a specific iasl to use, if needed
, console_loglevel ? "6" # 8=SPEW, 7=DEBUG, 6=INFO , console_loglevel ? "6" # 8=SPEW, 7=DEBUG, 6=INFO
@ -13,7 +11,6 @@
# these integers to ttyS* values is occasionally not the identity # these integers to ttyS* values is occasionally not the identity
# map. # map.
, uart-for-console ? throw "you must provide uart-for-console" , uart-for-console ? throw "you must provide uart-for-console"
, linux-command-line
}: }:
let let
@ -152,10 +149,7 @@ stdenv.mkDerivation {
"DEFAULT_CONSOLE_LOGLEVEL_${toString console_loglevel}" = lib.mkForce yes; "DEFAULT_CONSOLE_LOGLEVEL_${toString console_loglevel}" = lib.mkForce yes;
DEFAULT_CONSOLE_LOGLEVEL = lib.mkForce (freeform (toString console_loglevel)); DEFAULT_CONSOLE_LOGLEVEL = lib.mkForce (freeform (toString console_loglevel));
FMDFILE = lib.mkForce (freeform "${fmap}"); FMDFILE = lib.mkForce (freeform "${fmap}");
PAYLOAD_FILE = lib.mkForce (freeform "${payload}"); PAYLOAD_NONE = lib.mkForce yes;
LINUX_COMMAND_LINE = lib.mkForce (freeform "${linux-command-line}");
} // lib.optionalAttrs (initramfs_image != null) {
LINUX_INITRD = lib.mkForce (freeform "${initramfs_image}");
} // lib.optionalAttrs (uart-for-console != null) { } // lib.optionalAttrs (uart-for-console != null) {
UART_FOR_CONSOLE = lib.mkForce (freeform "${builtins.toString uart-for-console}"); UART_FOR_CONSOLE = lib.mkForce (freeform "${builtins.toString uart-for-console}");
} // lib.optionalAttrs (iasl != null) { } // lib.optionalAttrs (iasl != null) {

@ -26,7 +26,8 @@ let
in "console=${console} earlyprintk=${console}"; in "console=${console} earlyprintk=${console}";
iasl_20180531 = final.nixpkgsOnBuildForBuild.callPackage ./coreboot/iasl_20180531 { }; iasl_20180531 = final.nixpkgsOnBuildForBuild.callPackage ./coreboot/iasl_20180531 { };
coreboot = final.callPackage ./coreboot { coreboot = final.callPackage ./coreboot { };
image = final.callPackage ./image {
initramfs_image = final.initramfs; initramfs_image = final.initramfs;
}; };
kernel = final.callPackage ./kernel { }; kernel = final.callPackage ./kernel { };
@ -49,7 +50,7 @@ let
# totally different platform than the Device Under Test. # totally different platform than the Device Under Test.
# TODO(amjoseph): don't hardwire the chip type here # 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 # TODO(amjoseph): add a sanity check that (a) the image being

@ -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;
}

@ -2,7 +2,7 @@
{ nixpkgsOnBuildForHost { nixpkgsOnBuildForHost
, nixpkgsOnBuildForBuild , nixpkgsOnBuildForBuild
, lib , lib
, coreboot , image
, scripts , scripts
}: }:
@ -21,9 +21,9 @@ in nixpkgsOnBuildForHost.stdenv.mkDerivation (finalAttrs: {
runHook preInstall runHook preInstall
mkdir -p $out/{etc,bin} mkdir -p $out/{etc,bin}
ln -s ${coreboot}/coreboot.rom $out/ ln -s ${image}/coreboot.rom $out/
ln -s ${coreboot}/config $out/etc/coreboot.config ln -s ${image}/config $out/etc/coreboot.config
ln -s ${coreboot.passthru.fmap} $out/etc/coreboot.fmap ln -s ${image.passthru.fmap} $out/etc/coreboot.fmap
'' + (lib.concatStringsSep "\n" (lib.mapAttrsToList (scriptName: scriptText: '' '' + (lib.concatStringsSep "\n" (lib.mapAttrsToList (scriptName: scriptText: ''
ln -s ${writeShellScript scriptName scriptText} $out/bin/${scriptName}.sh ln -s ${writeShellScript scriptName scriptText} $out/bin/${scriptName}.sh

@ -19,9 +19,12 @@
console-device = "ttyS1"; console-device = "ttyS1";
image = prev.image.override {
payload = "${final.kernel}/bzImage";
};
coreboot = (prev.coreboot.override { coreboot = (prev.coreboot.override {
iasl = final.iasl_20180531; iasl = final.iasl_20180531;
payload = "${final.kernel}/bzImage";
coreboot-toolchain = with final.coreboot-toolchain; [ x64 i386 ]; coreboot-toolchain = with final.coreboot-toolchain; [ x64 i386 ];
fmap = ./custom.fmap; fmap = ./custom.fmap;
config = with lib.kernel; { config = with lib.kernel; {
@ -36,10 +39,6 @@
CBFS_SIZE = lib.mkForce (freeform "0x7FFAC8"); 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; CONSOLE_CBMEM = lib.mkForce no;
DRIVERS_INTEL_WIFI = lib.mkForce no; DRIVERS_INTEL_WIFI = lib.mkForce no;
HUDSON_XHCI_ENABLE = lib.mkForce no; HUDSON_XHCI_ENABLE = lib.mkForce no;

@ -31,10 +31,10 @@
${final.flashrom}/bin/flashrom -p internal $@ ${moreFlags} ${final.flashrom}/bin/flashrom -p internal $@ ${moreFlags}
''; '';
flashromWriteScript = moreFlags: flashromWriteScript = moreFlags:
flashromScript "-w ${final.coreboot}/coreboot.rom ${moreFlags}"; flashromScript "-w ${final.image}/coreboot.rom ${moreFlags}";
nvramToolScript = moreFlags: '' nvramToolScript = moreFlags: ''
set -euo pipefail 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 // { in prev.scripts // {
flashrom = flashromScript "$@"; flashrom = flashromScript "$@";
@ -51,7 +51,7 @@
nvram-tool = nvramToolScript "$@"; nvram-tool = nvramToolScript "$@";
nvram-all-read = nvramToolScript "-a"; nvram-all-read = nvramToolScript "-a";
nvram-all-write = nvramToolScript "-p $1"; 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-bootcount-show = nvramToolScript "-n -r reboot_counter";
nvram-parameter-read = nvramToolScript "-n -r $1"; nvram-parameter-read = nvramToolScript "-n -r $1";
nvram-parameter-choices = nvramToolScript "-e $1"; nvram-parameter-choices = nvramToolScript "-e $1";
@ -62,7 +62,7 @@
main = prev.main.overrideAttrs(previousAttrs: { main = prev.main.overrideAttrs(previousAttrs: {
# cmos nvram is an x86-ism # cmos nvram is an x86-ism
postInstall = (previousAttrs.postInstall or "") + '' postInstall = (previousAttrs.postInstall or "") + ''
ln -s ${final.coreboot}/{cmos.layout,cmos.default} $out/etc/ ln -s ${final.image}/{cmos.layout,cmos.default} $out/etc/
''; '';
}); });
})]; })];

@ -13,7 +13,7 @@
${final.flashrom}/bin/flashrom -p linux_mtd ${moreFlags} ${final.flashrom}/bin/flashrom -p linux_mtd ${moreFlags}
''; '';
flashromWriteScript = moreFlags: flashromWriteScript = moreFlags:
flashromScript "-w ${final.coreboot}/coreboot.rom ${moreFlags}"; flashromScript "-w ${final.image}/coreboot.rom ${moreFlags}";
in prev.scripts // { in prev.scripts // {
flashrom = flashromScript "$@"; flashrom = flashromScript "$@";
flash-write-fallback = flashromWriteScript "--fmap -i FALLBACK"; flash-write-fallback = flashromWriteScript "--fmap -i FALLBACK";

@ -73,12 +73,16 @@ in {
}; };
fit = final.nixpkgsOnBuildForBuild.callPackage (import ./fit) { 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 = coreboot =
(prev.coreboot.override { (prev.coreboot.override {
payload = "${final.fit}/Image.fit";
fmap = ./custom.fmap; fmap = ./custom.fmap;
config = with lib.kernel; { config = with lib.kernel; {
CBFS_PREFIX = lib.mkForce (freeform "prefix"); CBFS_PREFIX = lib.mkForce (freeform "prefix");
@ -99,12 +103,11 @@ in {
CONSOLE_SERIAL = lib.mkForce yes; CONSOLE_SERIAL = lib.mkForce yes;
#BOOTBLOCK_CONSOLE = lib.mkForce yes; #BOOTBLOCK_CONSOLE = lib.mkForce yes;
COMPRESS_SECONDARY_PAYLOAD = lib.mkForce no;
TPM_DEACTIVATE = lib.mkForce yes; TPM_DEACTIVATE = lib.mkForce yes;
PAYLOAD_FIT = lib.mkForce yes;
PAYLOAD_FIT_SUPPORT = lib.mkForce yes; PAYLOAD_FIT_SUPPORT = lib.mkForce yes;
COMPRESS_SECONDARY_PAYLOAD = lib.mkForce no;
DEBUG_CBFS = lib.mkForce yes; DEBUG_CBFS = lib.mkForce yes;
# maybe enable this # maybe enable this
@ -114,7 +117,6 @@ in {
ARM64_BL31_EXTERNAL_FILE = lib.mkForce (freeform "${final.atf}/bl31.elf"); ARM64_BL31_EXTERNAL_FILE = lib.mkForce (freeform "${final.atf}/bl31.elf");
}; };
coreboot-toolchain = with final.coreboot-toolchain; [ aarch64 ]; coreboot-toolchain = with final.coreboot-toolchain; [ aarch64 ];
initramfs_image = null; # it is part of the FIT image
uart-for-console = uart-for-console =
if final.console-device == "ttyS2" then 0 if final.console-device == "ttyS2" then 0
else if final.console-device == null then null else if final.console-device == null then null

@ -5,11 +5,29 @@
, ubootTools , ubootTools
, kernel , kernel
, initramfs , initramfs
, linux-command-line
}: }:
let let
initramfs_lzma = runCommand "initramfs.lzma" { } '' initramfs_lzma = runCommand "initramfs.lzma" { } ''
lzma < ${initramfs} > $out; 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 { in stdenv.mkDerivation {
name = "ownerboot-stage1-fit"; name = "ownerboot-stage1-fit";
dontUnpack = true; dontUnpack = true;
@ -58,7 +76,7 @@ in stdenv.mkDerivation {
}; };
fdt { fdt {
description = "rk3399-gru-kevin.dtb"; description = "rk3399-gru-kevin.dtb";
data = /incbin/("${kernel}/rk3399-gru-kevin.dtb"); data = /incbin/("${dtb-with-linux-command-line}");
type = "flat_dt"; type = "flat_dt";
arch = "arm64"; arch = "arm64";
compression = "none"; compression = "none";

@ -20,8 +20,8 @@
userspace = prev.userspace.overrideAttrs (a: { userspace = prev.userspace.overrideAttrs (a: {
postInstall = (a.postInstall or "") + '' postInstall = (a.postInstall or "") + ''
mkdir -p $out/etc mkdir -p $out/etc
cp ${final.coreboot.src}/src/mainboard/asus/kgpe-d16/cmos.layout $out/etc/ cp ${final.image.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.default $out/etc/
''; '';
}); });
@ -43,9 +43,12 @@
# TODO: use a NixOS-style structuredConfig for this. # TODO: use a NixOS-style structuredConfig for this.
cmos-default = null; cmos-default = null;
image = prev.image.override {
payload = "${final.kernel}/bzImage";
};
coreboot = (prev.coreboot.override { coreboot = (prev.coreboot.override {
iasl = final.iasl_20180531; iasl = final.iasl_20180531;
payload = "${final.kernel}/bzImage";
fmap = ./custom.fmap; fmap = ./custom.fmap;
config = with lib.kernel; { config = with lib.kernel; {
CBFS_PREFIX = lib.mkForce (freeform "prefix"); CBFS_PREFIX = lib.mkForce (freeform "prefix");
@ -84,10 +87,6 @@
NO_POST = lib.mkForce yes; 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_CBFS_GENERATE = lib.mkForce yes;
CPU_MICROCODE_MULTIPLE_FILES = lib.mkForce yes; CPU_MICROCODE_MULTIPLE_FILES = lib.mkForce yes;
CPU_UCODE_BINARIES = lib.mkForce (freeform ""); CPU_UCODE_BINARIES = lib.mkForce (freeform "");

Loading…
Cancel
Save