at master 7.2 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.hardware.deviceTree; 9 10 overlayType = lib.types.submodule { 11 options = { 12 name = lib.mkOption { 13 type = lib.types.str; 14 description = '' 15 Name of this overlay 16 ''; 17 }; 18 19 filter = lib.mkOption { 20 type = lib.types.nullOr lib.types.str; 21 default = null; 22 example = "*rpi*.dtb"; 23 description = '' 24 Only apply to .dtb files matching glob expression. 25 ''; 26 }; 27 28 dtsFile = lib.mkOption { 29 type = lib.types.nullOr lib.types.path; 30 description = '' 31 Path to .dts overlay file, overlay is applied to 32 each .dtb file matching "compatible" of the overlay. 33 ''; 34 default = null; 35 example = lib.literalExpression "./dts/overlays.dts"; 36 }; 37 38 dtsText = lib.mkOption { 39 type = lib.types.nullOr lib.types.str; 40 default = null; 41 description = '' 42 Literal DTS contents, overlay is applied to 43 each .dtb file matching "compatible" of the overlay. 44 ''; 45 example = '' 46 /dts-v1/; 47 /plugin/; 48 / { 49 compatible = "raspberrypi"; 50 }; 51 &{/soc} { 52 pps { 53 compatible = "pps-gpio"; 54 status = "okay"; 55 }; 56 }; 57 ''; 58 }; 59 60 dtboFile = lib.mkOption { 61 type = lib.types.nullOr lib.types.path; 62 default = null; 63 description = '' 64 Path to .dtbo compiled overlay file. 65 ''; 66 }; 67 }; 68 }; 69 70 filterDTBs = 71 src: 72 if cfg.filter == null then 73 src 74 else 75 pkgs.runCommand "dtbs-filtered" { } '' 76 mkdir -p $out 77 cd ${src} 78 find . -type f -name '${cfg.filter}' -print0 \ 79 | xargs -0 cp -v --no-preserve=mode --target-directory $out --parents 80 ''; 81 82 filteredDTBs = filterDTBs cfg.dtbSource; 83 84 # Fill in `dtboFile` for each overlay if not set already. 85 # Existence of one of these is guarded by assertion below 86 withDTBOs = 87 xs: 88 lib.flip map xs ( 89 o: 90 o 91 // { 92 dtboFile = 93 let 94 includePaths = [ 95 "${lib.getDev cfg.kernelPackage}/lib/modules/${cfg.kernelPackage.modDirVersion}/source/scripts/dtc/include-prefixes" 96 ] 97 ++ cfg.dtboBuildExtraIncludePaths; 98 extraPreprocessorFlags = cfg.dtboBuildExtraPreprocessorFlags; 99 in 100 if o.dtboFile == null then 101 let 102 dtsFile = if o.dtsFile == null then (pkgs.writeText "dts" o.dtsText) else o.dtsFile; 103 in 104 pkgs.deviceTree.compileDTS { 105 name = "${o.name}-dtbo"; 106 inherit includePaths extraPreprocessorFlags dtsFile; 107 } 108 else 109 o.dtboFile; 110 } 111 ); 112 113in 114{ 115 imports = [ 116 (lib.mkRemovedOptionModule [ 117 "hardware" 118 "deviceTree" 119 "base" 120 ] "Use hardware.deviceTree.kernelPackage instead") 121 ]; 122 123 options = { 124 hardware.deviceTree = { 125 enable = lib.mkOption { 126 default = pkgs.stdenv.hostPlatform.linux-kernel.DTB or false; 127 type = lib.types.bool; 128 description = '' 129 Build device tree files. These are used to describe the 130 non-discoverable hardware of a system. 131 ''; 132 }; 133 134 kernelPackage = lib.mkOption { 135 default = config.boot.kernelPackages.kernel; 136 defaultText = lib.literalExpression "config.boot.kernelPackages.kernel"; 137 example = lib.literalExpression "pkgs.linux_latest"; 138 type = lib.types.path; 139 description = '' 140 Kernel package where device tree include directory is from. Also used as default source of dtb package to apply overlays to 141 ''; 142 }; 143 144 dtboBuildExtraPreprocessorFlags = lib.mkOption { 145 default = [ ]; 146 example = lib.literalExpression "[ \"-DMY_DTB_DEFINE\" ]"; 147 type = lib.types.listOf lib.types.str; 148 description = '' 149 Additional flags to pass to the preprocessor during dtbo compilations 150 ''; 151 }; 152 153 dtboBuildExtraIncludePaths = lib.mkOption { 154 default = [ ]; 155 example = lib.literalExpression '' 156 [ 157 ./my_custom_include_dir_1 158 ./custom_include_dir_2 159 ] 160 ''; 161 type = lib.types.listOf lib.types.path; 162 description = '' 163 Additional include paths that will be passed to the preprocessor when creating the final .dts to compile into .dtbo 164 ''; 165 }; 166 167 dtbSource = lib.mkOption { 168 default = "${cfg.kernelPackage}/dtbs"; 169 defaultText = lib.literalExpression "\${cfg.kernelPackage}/dtbs"; 170 type = lib.types.path; 171 description = '' 172 Path to dtb directory that overlays and other processing will be applied to. Uses 173 device trees bundled with the Linux kernel by default. 174 ''; 175 }; 176 177 name = lib.mkOption { 178 default = null; 179 example = "some-dtb.dtb"; 180 type = lib.types.nullOr lib.types.str; 181 description = '' 182 The name of an explicit dtb to be loaded, relative to the dtb base. 183 Useful in extlinux scenarios if the bootloader doesn't pick the 184 right .dtb file from FDTDIR. 185 ''; 186 }; 187 188 filter = lib.mkOption { 189 type = lib.types.nullOr lib.types.str; 190 default = null; 191 example = "*rpi*.dtb"; 192 description = '' 193 Only include .dtb files matching glob expression. 194 ''; 195 }; 196 197 overlays = lib.mkOption { 198 default = [ ]; 199 example = lib.literalExpression '' 200 [ 201 { name = "pps"; dtsFile = ./dts/pps.dts; } 202 { name = "spi"; 203 dtsText = "..."; 204 } 205 { name = "precompiled"; dtboFile = ./dtbos/example.dtbo; } 206 ] 207 ''; 208 type = lib.types.listOf ( 209 lib.types.coercedTo lib.types.path (path: { 210 name = baseNameOf path; 211 filter = null; 212 dtboFile = path; 213 }) overlayType 214 ); 215 description = '' 216 List of overlays to apply to base device-tree (.dtb) files. 217 ''; 218 }; 219 220 package = lib.mkOption { 221 default = null; 222 type = lib.types.nullOr lib.types.path; 223 internal = true; 224 description = '' 225 A path containing the result of applying `overlays` to `kernelPackage`. 226 ''; 227 }; 228 }; 229 }; 230 231 config = lib.mkIf (cfg.enable) { 232 233 assertions = 234 let 235 invalidOverlay = o: (o.dtsFile == null) && (o.dtsText == null) && (o.dtboFile == null); 236 in 237 lib.singleton { 238 assertion = lib.all (o: !invalidOverlay o) cfg.overlays; 239 message = '' 240 deviceTree overlay needs one of dtsFile, dtsText or dtboFile set. 241 Offending overlay(s): 242 ${toString (map (o: o.name) (builtins.filter invalidOverlay cfg.overlays))} 243 ''; 244 }; 245 246 hardware.deviceTree.package = 247 if (cfg.overlays != [ ]) then 248 pkgs.deviceTree.applyOverlays filteredDTBs (withDTBOs cfg.overlays) 249 else 250 filteredDTBs; 251 }; 252}