diff --git a/nixos/modules/hardware/device-tree.nix b/nixos/modules/hardware/device-tree.nix index cf553497c89..b3f1dda98c8 100644 --- a/nixos/modules/hardware/device-tree.nix +++ b/nixos/modules/hardware/device-tree.nix @@ -22,11 +22,22 @@ in { example = literalExample "pkgs.device-tree_rpi"; type = types.path; description = '' - The package containing the base device-tree (.dtb) to boot. Contains + The path containing the base device-tree (.dtb) to boot. Contains device trees bundled with the Linux kernel by default. ''; }; + name = mkOption { + default = null; + example = "some-dtb.dtb"; + type = types.nullOr types.str; + description = '' + The name of an explicit dtb to be loaded, relative to the dtb base. + Useful in extlinux scenarios if the bootloader doesn't pick the + right .dtb file from FDTDIR. + ''; + }; + overlays = mkOption { default = []; example = literalExample diff --git a/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix b/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix index 2d34406a032..bef6cd2fb5a 100644 --- a/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix +++ b/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix @@ -2,12 +2,6 @@ # nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-aarch64.nix -A config.system.build.sdImage { config, lib, pkgs, ... }: -let - extlinux-conf-builder = - import ../../system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix { - pkgs = pkgs.buildPackages; - }; -in { imports = [ ../../profiles/base.nix @@ -56,7 +50,7 @@ in ''; populateRootCommands = '' mkdir -p ./files/boot - ${extlinux-conf-builder} -t 3 -c ${config.system.build.toplevel} -d ./files/boot + ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot ''; }; diff --git a/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix index 651d1a36dc1..d2ba611532e 100644 --- a/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix +++ b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix @@ -2,12 +2,6 @@ # nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix -A config.system.build.sdImage { config, lib, pkgs, ... }: -let - extlinux-conf-builder = - import ../../system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix { - pkgs = pkgs.buildPackages; - }; -in { imports = [ ../../profiles/base.nix @@ -53,7 +47,7 @@ in ''; populateRootCommands = '' mkdir -p ./files/boot - ${extlinux-conf-builder} -t 3 -c ${config.system.build.toplevel} -d ./files/boot + ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot ''; }; diff --git a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix index ba4127eaa0e..40a01f96177 100644 --- a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix +++ b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix @@ -2,12 +2,6 @@ # nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix -A config.system.build.sdImage { config, lib, pkgs, ... }: -let - extlinux-conf-builder = - import ../../system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix { - pkgs = pkgs.buildPackages; - }; -in { imports = [ ../../profiles/base.nix @@ -42,7 +36,7 @@ in ''; populateRootCommands = '' mkdir -p ./files/boot - ${extlinux-conf-builder} -t 3 -c ${config.system.build.toplevel} -d ./files/boot + ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot ''; }; diff --git a/nixos/modules/installer/cd-dvd/sd-image.nix b/nixos/modules/installer/cd-dvd/sd-image.nix index c15befa59e2..ddad1116c94 100644 --- a/nixos/modules/installer/cd-dvd/sd-image.nix +++ b/nixos/modules/installer/cd-dvd/sd-image.nix @@ -99,7 +99,7 @@ in }; populateRootCommands = mkOption { - example = literalExample "''\${extlinux-conf-builder} -t 3 -c \${config.system.build.toplevel} -d ./files/boot''"; + example = literalExample "''\${config.boot.loader.generic-extlinux-compatible.populateCmd} -c \${config.system.build.toplevel} -d ./files/boot''"; description = '' Shell commands to populate the ./files directory. All files in that directory are copied to the diff --git a/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix b/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix index af39c7bb684..416f8aeb1d3 100644 --- a/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix +++ b/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix @@ -4,11 +4,15 @@ with lib; let blCfg = config.boot.loader; + dtCfg = config.hardware.deviceTree; cfg = blCfg.generic-extlinux-compatible; timeoutStr = if blCfg.timeout == null then "-1" else toString blCfg.timeout; + # The builder used to write during system activation builder = import ./extlinux-conf-builder.nix { inherit pkgs; }; + # The builder exposed in populateCmd, which runs on the build architecture + populateBuilder = import ./extlinux-conf-builder.nix { pkgs = pkgs.buildPackages; }; in { options = { @@ -34,11 +38,28 @@ in Maximum number of configurations in the boot menu. ''; }; + + populateCmd = mkOption { + type = types.str; + readOnly = true; + description = '' + Contains the builder command used to populate an image, + honoring all options except the -c + argument. + Useful to have for sdImage.populateRootCommands + ''; + }; + }; }; - config = mkIf cfg.enable { - system.build.installBootLoader = "${builder} -g ${toString cfg.configurationLimit} -t ${timeoutStr} -c"; - system.boot.loader.id = "generic-extlinux-compatible"; - }; + config = let + builderArgs = "-g ${toString cfg.configurationLimit} -t ${timeoutStr}" + lib.optionalString (dtCfg.name != null) " -n ${dtCfg.name}"; + in + mkIf cfg.enable { + system.build.installBootLoader = "${builder} ${builderArgs} -c"; + system.boot.loader.id = "generic-extlinux-compatible"; + + boot.loader.generic-extlinux-compatible.populateCmd = "${populateBuilder} ${builderArgs}"; + }; } diff --git a/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh index 0092ee92b62..854684b87fa 100644 --- a/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh +++ b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh @@ -6,7 +6,7 @@ export PATH=/empty for i in @path@; do PATH=$PATH:$i/bin; done usage() { - echo "usage: $0 -t -c [-d ] [-g ]" >&2 + echo "usage: $0 -t -c [-d ] [-g ] [-n ]" >&2 exit 1 } @@ -15,7 +15,7 @@ default= # Default configuration target=/boot # Target directory numGenerations=0 # Number of other generations to include in the menu -while getopts "t:c:d:g:" opt; do +while getopts "t:c:d:g:n:" opt; do case "$opt" in t) # U-Boot interprets '0' as infinite and negative as instant boot if [ "$OPTARG" -lt 0 ]; then @@ -29,6 +29,7 @@ while getopts "t:c:d:g:" opt; do c) default="$OPTARG" ;; d) target="$OPTARG" ;; g) numGenerations="$OPTARG" ;; + n) dtbName="$OPTARG" ;; \?) usage ;; esac done @@ -96,7 +97,17 @@ addEntry() { echo " LINUX ../nixos/$(basename $kernel)" echo " INITRD ../nixos/$(basename $initrd)" if [ -d "$dtbDir" ]; then - echo " FDTDIR ../nixos/$(basename $dtbs)" + # if a dtbName was specified explicitly, use that, else use FDTDIR + if [ -n "$dtbName" ]; then + echo " FDT ../nixos/$(basename $dtbs)/${dtbName}" + else + echo " FDTDIR ../nixos/$(basename $dtbs)" + fi + else + if [ -n "$dtbName" ]; then + echo "Explicitly requested dtbName $dtbName, but there's no FDTDIR - bailing out." >&2 + exit 1 + fi fi echo " APPEND systemConfig=$path init=$path/init $extraParams" }