1 { config, lib, pkgs, ... }:
3 cfg = config.hardware.deviceTree;
5 overlayType = lib.types.submodule {
14 filter = lib.mkOption {
15 type = lib.types.nullOr lib.types.str;
17 example = "*rpi*.dtb";
19 Only apply to .dtb files matching glob expression.
23 dtsFile = lib.mkOption {
24 type = lib.types.nullOr lib.types.path;
26 Path to .dts overlay file, overlay is applied to
27 each .dtb file matching "compatible" of the overlay.
30 example = lib.literalExpression "./dts/overlays.dts";
33 dtsText = lib.mkOption {
34 type = lib.types.nullOr lib.types.str;
37 Literal DTS contents, overlay is applied to
38 each .dtb file matching "compatible" of the overlay.
44 compatible = "raspberrypi";
48 compatible = "pps-gpio";
55 dtboFile = lib.mkOption {
56 type = lib.types.nullOr lib.types.path;
59 Path to .dtbo compiled overlay file.
65 filterDTBs = src: if cfg.filter == null
68 pkgs.runCommand "dtbs-filtered" {} ''
71 find . -type f -name '${cfg.filter}' -print0 \
72 | xargs -0 cp -v --no-preserve=mode --target-directory $out --parents
75 filteredDTBs = filterDTBs cfg.dtbSource;
77 # Fill in `dtboFile` for each overlay if not set already.
78 # Existence of one of these is guarded by assertion below
79 withDTBOs = xs: lib.flip map xs (o: o // { dtboFile =
81 includePaths = ["${lib.getDev cfg.kernelPackage}/lib/modules/${cfg.kernelPackage.modDirVersion}/source/scripts/dtc/include-prefixes"] ++ cfg.dtboBuildExtraIncludePaths;
82 extraPreprocessorFlags = cfg.dtboBuildExtraPreprocessorFlags;
84 if o.dtboFile == null then
86 dtsFile = if o.dtsFile == null then (pkgs.writeText "dts" o.dtsText) else o.dtsFile;
88 pkgs.deviceTree.compileDTS {
89 name = "${o.name}-dtbo";
90 inherit includePaths extraPreprocessorFlags dtsFile;
97 (lib.mkRemovedOptionModule [ "hardware" "deviceTree" "base" ] "Use hardware.deviceTree.kernelPackage instead")
101 hardware.deviceTree = {
102 enable = lib.mkOption {
103 default = pkgs.stdenv.hostPlatform.linux-kernel.DTB or false;
104 type = lib.types.bool;
106 Build device tree files. These are used to describe the
107 non-discoverable hardware of a system.
111 kernelPackage = lib.mkOption {
112 default = config.boot.kernelPackages.kernel;
113 defaultText = lib.literalExpression "config.boot.kernelPackages.kernel";
114 example = lib.literalExpression "pkgs.linux_latest";
115 type = lib.types.path;
117 Kernel package where device tree include directory is from. Also used as default source of dtb package to apply overlays to
121 dtboBuildExtraPreprocessorFlags = lib.mkOption {
123 example = lib.literalExpression "[ \"-DMY_DTB_DEFINE\" ]";
124 type = lib.types.listOf lib.types.str;
126 Additional flags to pass to the preprocessor during dtbo compilations
130 dtboBuildExtraIncludePaths = lib.mkOption {
132 example = lib.literalExpression ''
134 ./my_custom_include_dir_1
135 ./custom_include_dir_2
138 type = lib.types.listOf lib.types.path;
140 Additional include paths that will be passed to the preprocessor when creating the final .dts to compile into .dtbo
144 dtbSource = lib.mkOption {
145 default = "${cfg.kernelPackage}/dtbs";
146 defaultText = lib.literalExpression "\${cfg.kernelPackage}/dtbs";
147 type = lib.types.path;
149 Path to dtb directory that overlays and other processing will be applied to. Uses
150 device trees bundled with the Linux kernel by default.
154 name = lib.mkOption {
156 example = "some-dtb.dtb";
157 type = lib.types.nullOr lib.types.str;
159 The name of an explicit dtb to be loaded, relative to the dtb base.
160 Useful in extlinux scenarios if the bootloader doesn't pick the
161 right .dtb file from FDTDIR.
165 filter = lib.mkOption {
166 type = lib.types.nullOr lib.types.str;
168 example = "*rpi*.dtb";
170 Only include .dtb files matching glob expression.
174 overlays = lib.mkOption {
176 example = lib.literalExpression ''
178 { name = "pps"; dtsFile = ./dts/pps.dts; }
182 { name = "precompiled"; dtboFile = ./dtbos/example.dtbo; }
185 type = lib.types.listOf (lib.types.coercedTo lib.types.path (path: {
186 name = baseNameOf path;
191 List of overlays to apply to base device-tree (.dtb) files.
195 package = lib.mkOption {
197 type = lib.types.nullOr lib.types.path;
200 A path containing the result of applying `overlays` to `kernelPackage`.
206 config = lib.mkIf (cfg.enable) {
209 invalidOverlay = o: (o.dtsFile == null) && (o.dtsText == null) && (o.dtboFile == null);
211 assertion = lib.all (o: !invalidOverlay o) cfg.overlays;
213 deviceTree overlay needs one of dtsFile, dtsText or dtboFile set.
214 Offending overlay(s):
215 ${toString (map (o: o.name) (builtins.filter invalidOverlay cfg.overlays))}
219 hardware.deviceTree.package = if (cfg.overlays != [])
220 then pkgs.deviceTree.applyOverlays filteredDTBs (withDTBOs cfg.overlays)