about summary refs log tree commit diff
diff options
context:
space:
mode:
-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/default.nix17
-rw-r--r--pkgs/os-specific/linux/device-tree/raspberrypi.nix32
-rw-r--r--pkgs/top-level/all-packages.nix4
7 files changed, 114 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..f57502d4c83e
--- /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_rpi";
+          type = 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_rpi.overlays}/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;
+          internal = true;
+          description = ''
+            A path containing the result of applying `overlays` to `base`.
+          '';
+        };
+      };
+  };
+
+  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 87fcce875253..a167336c156b 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/default.nix b/pkgs/os-specific/linux/device-tree/default.nix
new file mode 100644
index 000000000000..13d819a08a5b
--- /dev/null
+++ b/pkgs/os-specific/linux/device-tree/default.nix
@@ -0,0 +1,17 @@
+{ stdenvNoCC, dtc, findutils }:
+
+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
+    '';
+  });
+}
diff --git a/pkgs/os-specific/linux/device-tree/raspberrypi.nix b/pkgs/os-specific/linux/device-tree/raspberrypi.nix
new file mode 100644
index 000000000000..a77200a68f7d
--- /dev/null
+++ b/pkgs/os-specific/linux/device-tree/raspberrypi.nix
@@ -0,0 +1,32 @@
+{ stdenvNoCC, raspberrypifw }:
+
+stdenvNoCC.mkDerivation {
+  name = "raspberrypi-dtbs-${raspberrypifw.version}";
+  nativeBuildInputs = [ raspberrypifw ];
+
+  # Rename DTBs so u-boot finds them, like linux-rpi.nix
+  buildCommand = ''
+    mkdir -p $out/broadcom/
+    cd $out/broadcom/
+
+    cp ${raspberrypifw}/share/raspberrypi/boot/bcm*.dtb .
+
+    cp bcm2708-rpi-0-w.dtb bcm2835-rpi-zero-w.dtb
+    cp bcm2708-rpi-b.dtb bcm2835-rpi-a.dtb
+    cp bcm2708-rpi-b.dtb bcm2835-rpi-b.dtb
+    cp bcm2708-rpi-b.dtb bcm2835-rpi-b-rev2.dtb
+    cp bcm2708-rpi-b-plus.dtb bcm2835-rpi-a-plus
+    cp bcm2708-rpi-b-plus.dtb bcm2835-rpi-b-plus
+    cp bcm2708-rpi-b-plus.dtb bcm2835-rpi-zero.dtb
+    cp bcm2708-rpi-cm.dtb bcm2835-rpi-cm.dtb
+    cp bcm2709-rpi-2-b.dtb bcm2836-rpi-2-b.dtb
+    cp bcm2710-rpi-3-b.dtb bcm2837-rpi-3-b.dtb
+    cp bcm2710-rpi-3-b-plus.dtb bcm2837-rpi-3-b-plus.dtb
+    cp bcm2710-rpi-cm3.dtb bcm2837-rpi-cm3.dtb
+  '';
+
+  passthru = {
+    # Compatible overlays that may be used
+    overlays = "${raspberrypifw}/share/raspberrypi/boot/overlays";
+  };
+}
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index dcba04a43b6f..ae24b113fa16 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -169,6 +169,10 @@ in
 
   demoit = callPackage ../servers/demoit { };
 
+  deviceTree = callPackage ../os-specific/linux/device-tree {};
+
+  device-tree_rpi = callPackage ../os-specific/linux/device-tree/raspberrypi.nix {};
+
   diffPlugins = (callPackage ../build-support/plugins.nix {}).diffPlugins;
 
   dieHook = makeSetupHook {} ../build-support/setup-hooks/die.sh;