diff --git a/nixos/modules/hardware/device-tree.nix b/nixos/modules/hardware/device-tree.nix index c568f52ab677..6ab13c0eb709 100644 --- a/nixos/modules/hardware/device-tree.nix +++ b/nixos/modules/hardware/device-tree.nix @@ -66,36 +66,32 @@ let }; filterDTBs = src: if cfg.filter == null - then "${src}/dtbs" + then src else pkgs.runCommand "dtbs-filtered" {} '' mkdir -p $out - cd ${src}/dtbs + cd ${src} find . -type f -name '${cfg.filter}' -print0 \ | xargs -0 cp -v --no-preserve=mode --target-directory $out --parents ''; - filteredDTBs = filterDTBs cfg.kernelPackage; - - # Compile single Device Tree overlay source - # file (.dts) into its compiled variant (.dtbo) - compileDTS = name: f: pkgs.callPackage({ stdenv, dtc }: stdenv.mkDerivation { - name = "${name}-dtbo"; - - nativeBuildInputs = [ dtc ]; - - buildCommand = '' - $CC -E -nostdinc -I${getDev cfg.kernelPackage}/lib/modules/${cfg.kernelPackage.modDirVersion}/source/scripts/dtc/include-prefixes -undef -D__DTS__ -x assembler-with-cpp ${f} | \ - dtc -I dts -O dtb -@ -o $out - ''; - }) {}; + filteredDTBs = filterDTBs cfg.dtbSource; # Fill in `dtboFile` for each overlay if not set already. # Existence of one of these is guarded by assertion below withDTBOs = xs: flip map xs (o: o // { dtboFile = + let + includePaths = ["${getDev cfg.kernelPackage}/lib/modules/${cfg.kernelPackage.modDirVersion}/source/scripts/dtc/include-prefixes"] ++ cfg.dtboBuildExtraIncludePaths; + extraPreprocessorFlags = cfg.dtboBuildExtraPreprocessorFlags; + in if o.dtboFile == null then - if o.dtsFile != null then compileDTS o.name o.dtsFile - else compileDTS o.name (pkgs.writeText "dts" o.dtsText) + let + dtsFile = if o.dtsFile == null then (pkgs.writeText "dts" o.dtsText) else o.dtsFile; + in + pkgs.deviceTree.compileDTS { + name = "${o.name}-dtbo"; + inherit includePaths extraPreprocessorFlags dtsFile; + } else o.dtboFile; } ); in @@ -121,7 +117,39 @@ in example = literalExpression "pkgs.linux_latest"; type = types.path; description = lib.mdDoc '' - Kernel package containing the base device-tree (.dtb) to boot. Uses + Kernel package where device tree include directory is from. Also used as default source of dtb package to apply overlays to + ''; + }; + + dtboBuildExtraPreprocessorFlags = mkOption { + default = []; + example = literalExpression "[ \"-DMY_DTB_DEFINE\" ]"; + type = types.listOf types.str; + description = lib.mdDoc '' + Additional flags to pass to the preprocessor during dtbo compilations + ''; + }; + + dtboBuildExtraIncludePaths = mkOption { + default = []; + example = literalExpression '' + [ + ./my_custom_include_dir_1 + ./custom_include_dir_2 + ] + ''; + type = types.listOf types.path; + description = lib.mdDoc '' + Additional include paths that will be passed to the preprocessor when creating the final .dts to compile into .dtbo + ''; + }; + + dtbSource = mkOption { + default = "${cfg.kernelPackage}/dtbs"; + defaultText = literalExpression "\${cfg.kernelPackage}/dtbs"; + type = types.path; + description = lib.mdDoc '' + Path to dtb directory that overlays and other processing will be applied to. Uses device trees bundled with the Linux kernel by default. ''; }; diff --git a/pkgs/os-specific/linux/device-tree/default.nix b/pkgs/os-specific/linux/device-tree/default.nix index fb8e92f23306..1a50d799b4b1 100644 --- a/pkgs/os-specific/linux/device-tree/default.nix +++ b/pkgs/os-specific/linux/device-tree/default.nix @@ -1,6 +1,29 @@ -{ lib, stdenvNoCC, dtc }: +{ lib, stdenv, stdenvNoCC, dtc }: with lib; { + # Compile single Device Tree overlay source + # file (.dts) into its compiled variant (.dtb) + compileDTS = ({ + name, + dtsFile, + includePaths ? [], + extraPreprocessorFlags ? [] + }: stdenv.mkDerivation { + inherit name; + + nativeBuildInputs = [ dtc ]; + + buildCommand = + let + includeFlagsStr = lib.concatMapStringsSep " " (includePath: "-I${includePath}") includePaths; + extraPreprocessorFlagsStr = lib.concatStringsSep " " extraPreprocessorFlags; + in + '' + $CC -E -nostdinc ${includeFlagsStr} -undef -D__DTS__ -x assembler-with-cpp ${extraPreprocessorFlagsStr} ${dtsFile} | \ + dtc -I dts -O dtb -@ -o $out + ''; + }); + applyOverlays = (base: overlays': stdenvNoCC.mkDerivation { name = "device-tree-overlays"; nativeBuildInputs = [ dtc ];