Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: NixOS/nixpkgs
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: ca2fd92dadea
Choose a base ref
...
head repository: NixOS/nixpkgs
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f0f88be1eabf
Choose a head ref
  • 2 commits
  • 3 files changed
  • 4 contributors

Commits on Sep 9, 2020

  1. nixos/device-tree: improve overlays support

    Now allows applying external overlays either in form of
    .dts file, literal dts context added to store or precompiled .dtbo.
    
    If overlays are defined, kernel device-trees are compiled with '-@'
    so the .dtb files contain symbols which we can reference in our
    overlays.
    
    Since `fdtoverlay` doesn't respect `/ compatible` by itself
    we query compatible strings of both `dtb` and `dtbo(verlay)`
    and apply only if latter is substring of the former.
    
    Also adds support for filtering .dtb files (as there are now nearly 1k
    dtbs).
    
    Co-authored-by: georgewhewell <georgerw@gmail.com>
    Co-authored-by: Kai Wohlfahrt <kai.wohlfahrt@gmail.com>
    3 people committed Sep 9, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6c9df40 View commit details
  2. Merge pull request #79370 from sorki/dtoverlays

    Improve device-tree overlay support
    worldofpeace authored Sep 9, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    f0f88be View commit details
Showing with 183 additions and 19 deletions.
  1. +11 −0 nixos/doc/manual/release-notes/rl-2009.xml
  2. +151 −13 nixos/modules/hardware/device-tree.nix
  3. +21 −6 pkgs/os-specific/linux/device-tree/default.nix
11 changes: 11 additions & 0 deletions nixos/doc/manual/release-notes/rl-2009.xml
Original file line number Diff line number Diff line change
@@ -843,6 +843,17 @@ CREATE ROLE postgres LOGIN SUPERUSER;
of the default <literal>out</literal> output anymore - if you relied on the
<literal>notmuch-emacs-mua</literal> binary or the emacs lisp files, access them via
the <literal>notmuch.emacs</literal> output.

Device tree overlay support was improved in
<link xlink:href="https://github.com/NixOS/nixpkgs/pull/79370">#79370</link>
and now uses <xref linkend="opt-hardware.deviceTree.kernelPackage"/>
instead of <option>hardware.deviceTree.base</option>.

<xref linkend="opt-hardware.deviceTree.overlays"/> configuration was
extended to support <literal>.dts</literal> files with symbols.

Device trees can now be filtered by setting
<xref linkend="opt-hardware.deviceTree.filter"/> option.
</para>
</listitem>
<listitem>
164 changes: 151 additions & 13 deletions nixos/modules/hardware/device-tree.nix
Original file line number Diff line number Diff line change
@@ -4,7 +4,114 @@ with lib;

let
cfg = config.hardware.deviceTree;
in {

overlayType = types.submodule {
options = {
name = mkOption {
type = types.str;
description = ''
Name of this overlay
'';
};

dtsFile = mkOption {
type = types.nullOr types.path;
description = ''
Path to .dts overlay file, overlay is applied to
each .dtb file matching "compatible" of the overlay.
'';
default = null;
example = literalExample "./dts/overlays.dts";
};

dtsText = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Literal DTS contents, overlay is applied to
each .dtb file matching "compatible" of the overlay.
'';
example = literalExample ''
/dts-v1/;
/plugin/;
/ {
compatible = "raspberrypi";
fragment@0 {
target-path = "/soc";
__overlay__ {
pps {
compatible = "pps-gpio";
status = "okay";
};
};
};
};
'';
};

dtboFile = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
Path to .dtbo compiled overlay file.
'';
};
};
};

# this requires kernel package
dtbsWithSymbols = pkgs.stdenv.mkDerivation {
name = "dtbs-with-symbols";
inherit (cfg.kernelPackage) src nativeBuildInputs depsBuildBuild;
patches = map (patch: patch.patch) cfg.kernelPackage.kernelPatches;
buildPhase = ''
patchShebangs scripts/*
substituteInPlace scripts/Makefile.lib \
--replace 'DTC_FLAGS += $(DTC_FLAGS_$(basetarget))' 'DTC_FLAGS += $(DTC_FLAGS_$(basetarget)) -@'
make ${pkgs.stdenv.hostPlatform.platform.kernelBaseConfig} ARCH="${pkgs.stdenv.hostPlatform.platform.kernelArch}"
make dtbs ARCH="${pkgs.stdenv.hostPlatform.platform.kernelArch}"
'';
installPhase = ''
make dtbs_install INSTALL_DTBS_PATH=$out/dtbs ARCH="${pkgs.stdenv.hostPlatform.platform.kernelArch}"
'';
};

filterDTBs = src: if isNull cfg.filter
then "${src}/dtbs"
else
pkgs.runCommand "dtbs-filtered" {} ''
mkdir -p $out
cd ${src}/dtbs
find . -type f -name '${cfg.filter}' -print0 \
| xargs -0 cp -v --no-preserve=mode --target-directory $out --parents
'';

# Compile single Device Tree overlay source
# file (.dts) into its compiled variant (.dtbo)
compileDTS = name: f: pkgs.callPackage({ dtc }: pkgs.stdenv.mkDerivation {
name = "${name}-dtbo";

nativeBuildInputs = [ dtc ];

buildCommand = ''
dtc -I dts ${f} -O dtb -@ -o $out
'';
}) {};

# 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 =
if isNull o.dtboFile then
if !isNull o.dtsFile then compileDTS o.name o.dtsFile
else compileDTS o.name (pkgs.writeText "dts" o.dtsText)
else o.dtboFile; } );

in
{
imports = [
(mkRemovedOptionModule [ "hardware" "deviceTree" "base" ] "Use hardware.deviceTree.kernelPackage instead")
];

options = {
hardware.deviceTree = {
enable = mkOption {
@@ -16,13 +123,13 @@ in {
'';
};

base = mkOption {
default = "${config.boot.kernelPackages.kernel}/dtbs";
defaultText = "\${config.boot.kernelPackages.kernel}/dtbs";
example = literalExample "pkgs.device-tree_rpi";
kernelPackage = mkOption {
default = config.boot.kernelPackages.kernel;
defaultText = "config.boot.kernelPackages.kernel";
example = literalExample "pkgs.linux_latest";
type = types.path;
description = ''
The path containing the base device-tree (.dtb) to boot. Contains
Kernel package containing the base device-tree (.dtb) to boot. Uses
device trees bundled with the Linux kernel by default.
'';
};
@@ -38,14 +145,32 @@ in {
'';
};

filter = mkOption {
type = types.nullOr types.str;
default = null;
example = "*rpi*.dtb";
description = ''
Only include .dtb files matching glob expression.
'';
};

overlays = mkOption {
default = [];
example = literalExample
"[\"\${pkgs.device-tree_rpi.overlays}/w1-gpio.dtbo\"]";
type = types.listOf types.path;
example = literalExample ''
[
{ name = "pps"; dtsFile = ./dts/pps.dts; }
{ name = "spi";
dtsText = "...";
}
{ name = "precompiled"; dtboFile = ./dtbos/example.dtbo; }
]
'';
type = types.listOf (types.coercedTo types.path (path: {
name = baseNameOf path;
dtboFile = path;
}) overlayType);
description = ''
A path containing device tree overlays (.dtbo) to be applied to all
base device-trees.
List of overlays to apply to base device-tree (.dtb) files.
'';
};

@@ -54,14 +179,27 @@ in {
type = types.nullOr types.path;
internal = true;
description = ''
A path containing the result of applying `overlays` to `base`.
A path containing the result of applying `overlays` to `kernelPackage`.
'';
};
};
};

config = mkIf (cfg.enable) {

assertions = let
invalidOverlay = o: isNull o.dtsFile && isNull o.dtsText && isNull o.dtboFile;
in lib.singleton {
assertion = lib.all (o: !invalidOverlay o) cfg.overlays;
message = ''
deviceTree overlay needs one of dtsFile, dtsText or dtboFile set.
Offending overlay(s):
${toString (map (o: o.name) (builtins.filter invalidOverlay cfg.overlays))}
'';
};

hardware.deviceTree.package = if (cfg.overlays != [])
then pkgs.deviceTree.applyOverlays cfg.base cfg.overlays else cfg.base;
then pkgs.deviceTree.applyOverlays (filterDTBs dtbsWithSymbols) (withDTBOs cfg.overlays)
else (filterDTBs cfg.kernelPackage);
};
}
27 changes: 21 additions & 6 deletions pkgs/os-specific/linux/device-tree/default.nix
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
{ stdenvNoCC, dtc, findutils }:

with stdenvNoCC.lib; {
applyOverlays = (base: overlays: stdenvNoCC.mkDerivation {
applyOverlays = (base: overlays': stdenvNoCC.mkDerivation {
name = "device-tree-overlays";
nativeBuildInputs = [ dtc findutils ];
buildCommand = let
quotedDtbos = concatMapStringsSep " " (o: "\"${toString o}\"") (toList overlays);
overlays = 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};
mkdir -p $out
cd ${base}
find . -type f -name '*.dtb' -print0 \
| xargs -0 cp -v --no-preserve=mode --target-directory $out --parents
for dtb in $(find $out -type f -name '*.dtb'); do
dtbCompat="$( fdtget -t s $dtb / compatible )"
${flip (concatMapStringsSep "\n") overlays (o: ''
overlayCompat="$( fdtget -t s ${o.dtboFile} / compatible )"
# overlayCompat in dtbCompat
if [[ "$dtbCompat" =~ "$overlayCompat" ]]; then
echo "Applying overlay ${o.name} to $( basename $dtb )"
mv $dtb{,.in}
fdtoverlay -o "$dtb" -i "$dtb.in" ${o.dtboFile};
rm $dtb.in
fi
'')}
done
'';
});