nixboot/coreboot.nix

160 lines
4.1 KiB
Nix

{ lib, stdenv, fetchurl, fetchgit
, linkFarm, overrideCC
, writeText, writeShellScriptBin
, gnat, bison, flex, zlib, python3
, libfaketime, gnumake
# options
, rev # coreboot git revision
, sources # coreboot sources attrset
, arch ? "i386" # target architecture
, conf ? { } # coreboot configuration
, postCommands ? "" # command to run after build
}:
let
adaStdenv = overrideCC stdenv gnat;
version = lib.substring 0 6 rev;
in rec {
## Sources
# coreboot source
src = fetchgit {
url = "https://review.coreboot.org/coreboot.git";
fetchSubmodules = true;
inherit (sources) rev sha256;
};
# seabios source
seabios = builtins.fetchGit {
url = "https://review.coreboot.org/seabios.git";
rev = conf.seabios.revision-id;
};
# tarballs needed to build the toolchain
tarballs = linkFarm "toolchain-tarballs"
(map (file: { name = file.name; path = toString file; })
sources.toolchain);
## Helpers
# converts Nix attrs to Kconfig format
toConf = prefix: name: val:
let
name' = lib.replaceStrings ["-"] ["_"] (lib.toUpper name);
val' = if lib.isBool val then (if val then "y" else "n")
else builtins.toJSON val;
sub = "${prefix}_${name'}";
in
if lib.isAttrs val && ! lib.isDerivation val
then (lib.concatStringsSep "\n"
(lib.mapAttrsToList (toConf sub) val))
else "${prefix}_${name'}=${val'}";
# the coreboot Kconfig file
defConfig = with lib;
writeText "defconfig"
(concatStringsSep "\n"
(mapAttrsToList (toConf "CONFIG") conf));
# returns the current revision
fakegit = writeShellScriptBin "git" "echo ${version}";
# does nothing, just to trick buildgcc
fakecurl = writeShellScriptBin "curl" "echo curl 1.2.3";
# runs make with faketime for determinism
faketime = writeShellScriptBin "make" ''
exec ${libfaketime}/bin/faketime -f '1970-01-01 00:00:01' \
${gnumake}/bin/make "$@"
'';
## Packages
# the coreboot compilers toolchain
toolchain = adaStdenv.mkDerivation {
pname = "coreboot-toolchain";
inherit version src;
nativeBuildInputs = [
fakecurl fakegit
bison flex zlib
];
# link source tarballs
preBuild = "ln -s ${tarballs} util/crossgcc/tarballs";
# https://github.com/NixOS/nixpkgs/pull/107435
hardeningDisable = [ "format" ];
makeFlags =
[ "CPUS=$(NIX_BUILD_CORES)"
"DEST=$(out)"
"crossgcc-${arch}"
];
dontInstall = true;
meta = with stdenv.lib; {
description = "Coreboot compilers toolchain";
homepage = "https://www.coreboot.org";
license = licenses.gpl2Only;
platforms = platforms.all;
};
};
# the final coreboot rom
coreboot = stdenv.mkDerivation {
pname = "coreboot";
inherit src version;
nativeBuildInputs = [ faketime fakegit ]
++ lib.optional ( conf ? "use-me-cleaner"
|| conf ? "seabios") python3;
postPatch = "patchShebangs .";
preBuild = ''
# write default configuration
cp ${defConfig} .config
make olddefconfig
# copy payload
${lib.optionalString (conf ? "seabios") ''
cp -r ${seabios} payloads/external/SeaBIOS/seabios
chmod -R +w payloads/external/SeaBIOS/seabios
''}
'';
makeFlags =
[ "ARCH=${arch}"
# https://review.coreboot.org/c/coreboot/+/48937
"XGCCPATH=${toolchain}/bin/"
];
postBuild = postCommands;
installPhase = ''
install -Dm644 build/coreboot.rom $out/coreboot.rom
install -Dm644 .config $out/config
make savedefconfig DEFCONFIG=$out/defconfig
'';
meta = {
description = "Fast, secure and flexible OpenSource firmware";
longDescription = ''
coreboot is an extended firmware platform that delivers a lightning
fast and secure boot experience on modern computers and embedded
systems. As an Open Source project it provides auditability and maximum
control over technology.
'';
homepage = "https://www.coreboot.org";
license = lib.licenses.gpl2Only;
platforms = lib.platforms.all;
};
};
}