about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKai Wohlfahrt <kai@prodo.ai>2019-04-24 18:24:16 +0100
committerKai Wohlfahrt <kai@prodo.ai>2019-08-07 13:51:22 +0100
commitdd0a9512797faa83bd1f974b10ef4d620200a79a (patch)
tree5b97f95445c6e3724520f184cdedd6d4d25d9827
parent0a477846af2837752687ced588b71108ff010bb2 (diff)
downloadnixlib-dd0a9512797faa83bd1f974b10ef4d620200a79a.tar
nixlib-dd0a9512797faa83bd1f974b10ef4d620200a79a.tar.gz
nixlib-dd0a9512797faa83bd1f974b10ef4d620200a79a.tar.bz2
nixlib-dd0a9512797faa83bd1f974b10ef4d620200a79a.tar.lz
nixlib-dd0a9512797faa83bd1f974b10ef4d620200a79a.tar.xz
nixlib-dd0a9512797faa83bd1f974b10ef4d620200a79a.tar.zst
nixlib-dd0a9512797faa83bd1f974b10ef4d620200a79a.zip
nixos/hardware.deviceTree: new module
Add support for custom device-tree files, and applying overlays to them.
This is useful for supporting non-discoverable hardware, such as sensors
attached to GPIO pins on a Raspberry Pi.
-rw-r--r--nixos/modules/hardware/device-tree.nix56
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/system/activation/top-level.nix4
-rw-r--r--nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh5
-rw-r--r--pkgs/os-specific/linux/device-tree.nix28
-rw-r--r--pkgs/top-level/all-packages.nix2
6 files changed, 91 insertions, 5 deletions
diff --git a/nixos/modules/hardware/device-tree.nix b/nixos/modules/hardware/device-tree.nix
new file mode 100644
index 000000000000..200669395728
--- /dev/null
+++ b/nixos/modules/hardware/device-tree.nix
@@ -0,0 +1,56 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.hardware.deviceTree;
+in {
+  options = {
+      hardware.deviceTree = {
+        enable = mkOption {
+          default = pkgs.stdenv.hostPlatform.platform.kernelDTB or false;
+          type = types.bool;
+          description = ''
+            Build device tree files. These are used to describe the
+            non-discoverable hardware of a system.
+          '';
+        };
+
+        base = mkOption {
+          default = "${config.boot.kernelPackages.kernel}/dtbs";
+          defaultText = "\${config.boot.kernelPackages.kernel}/dtbs";
+          example = literalExample "pkgs.deviceTree.raspberryPiDtbs";
+          type = types.nullOr types.path;
+          description = ''
+            The package containing the base device-tree (.dtb) to boot. Contains
+            device trees bundled with the Linux kernel by default.
+          '';
+        };
+
+        overlays = mkOption {
+          default = [];
+          example = literalExample
+            "[\"\${pkgs.deviceTree.raspberryPiOverlays}/w1-gpio.dtbo\"]";
+          type = types.listOf types.path;
+          description = ''
+            A path containing device tree overlays (.dtbo) to be applied to all
+            base device-trees.
+          '';
+        };
+
+        package = mkOption {
+          default = null;
+          type = types.nullOr types.path;
+          description = ''
+            A path containing device tree overlays (.dtbo) to be applied to all
+            base device-trees. Overrides `base` and `overlays`.
+          '';
+        };
+      };
+  };
+
+  config = mkIf (cfg.enable) {
+    hardware.deviceTree.package = if (cfg.overlays != [])
+      then pkgs.deviceTree.applyOverlays cfg.base cfg.overlays else cfg.base;
+  };
+}
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 15990177d741..cf00fecc44fa 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -46,6 +46,7 @@
   ./hardware/cpu/amd-microcode.nix
   ./hardware/cpu/intel-microcode.nix
   ./hardware/digitalbitbox.nix
+  ./hardware/device-tree.nix
   ./hardware/sensor/iio.nix
   ./hardware/ksm.nix
   ./hardware/ledger.nix
diff --git a/nixos/modules/system/activation/top-level.nix b/nixos/modules/system/activation/top-level.nix
index 5c88d27b6c65..f67d29005616 100644
--- a/nixos/modules/system/activation/top-level.nix
+++ b/nixos/modules/system/activation/top-level.nix
@@ -46,8 +46,8 @@ let
 
         ln -s ${kernelPath} $out/kernel
         ln -s ${config.system.modulesTree} $out/kernel-modules
-        ${optionalString (pkgs.stdenv.hostPlatform.platform.kernelDTB or false) ''
-          ln -s ${config.boot.kernelPackages.kernel}/dtbs $out/dtbs
+        ${optionalString (config.hardware.deviceTree.package != null) ''
+          ln -s ${config.hardware.deviceTree.package} $out/dtbs
         ''}
 
         echo -n "$kernelParams" > $out/kernel-params
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 c780a89b102c..0092ee92b62f 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
@@ -75,9 +75,8 @@ addEntry() {
 
     copyToKernelsDir "$path/kernel"; kernel=$result
     copyToKernelsDir "$path/initrd"; initrd=$result
-    # XXX UGLY: maybe the system config should have a top-level "dtbs" entry?
-    dtbDir=$(readlink -m "$path/kernel/../dtbs")
-    if [ -d "$dtbDir" ]; then
+    dtbDir=$(readlink -m "$path/dtbs")
+    if [ -e "$dtbDir" ]; then
         copyToKernelsDir "$dtbDir"; dtbs=$result
     fi
 
diff --git a/pkgs/os-specific/linux/device-tree.nix b/pkgs/os-specific/linux/device-tree.nix
new file mode 100644
index 000000000000..81dccac8b8c8
--- /dev/null
+++ b/pkgs/os-specific/linux/device-tree.nix
@@ -0,0 +1,28 @@
+{ stdenvNoCC, dtc, findutils, raspberrypifw }:
+
+with stdenvNoCC.lib; {
+  applyOverlays = (base: overlays: stdenvNoCC.mkDerivation {
+    name = "device-tree-overlays";
+    nativeBuildInputs = [ dtc findutils ];
+    buildCommand = let
+      quotedDtbos = concatMapStringsSep " " (o: "\"${toString o}\"") (toList overlays);
+    in ''
+      for dtb in $(find ${base} -name "*.dtb" ); do
+        outDtb=$out/$(realpath --relative-to "${base}" "$dtb")
+        mkdir -p "$(dirname "$outDtb")"
+        fdtoverlay -o "$outDtb" -i "$dtb" ${quotedDtbos};
+      done
+    '';
+  });
+
+  raspberryPiDtbs = stdenvNoCC.mkDerivation {
+    name = "raspberrypi-dtbs-${raspberrypifw.version}";
+    nativeBuildInputs = [ raspberrypifw ];
+    buildCommand = ''
+      mkdir -p $out/broadcom/
+      cp ${raspberrypifw}/share/raspberrypi/boot/bcm*.dtb $out/broadcom
+    '';
+  };
+
+  raspberryPiOverlays = "${raspberrypifw}/share/raspberrypi/boot/overlays";
+}
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 25515fe593c2..44cd12b4db6c 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -169,6 +169,8 @@ in
 
   demoit = callPackage ../servers/demoit { };
 
+  deviceTree = callPackage ../os-specific/linux/device-tree.nix {};
+
   diffPlugins = (callPackage ../build-support/plugins.nix {}).diffPlugins;
 
   dieHook = makeSetupHook {} ../build-support/setup-hooks/die.sh;