summary refs log tree commit diff
path: root/pkgs/os-specific/linux/device-tree/default.nix
blob: fb8e92f233063a14ef63f7fb9baaf239522b7185 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
{ lib, stdenvNoCC, dtc }:

with lib; {
  applyOverlays = (base: overlays': stdenvNoCC.mkDerivation {
    name = "device-tree-overlays";
    nativeBuildInputs = [ dtc ];
    buildCommand = let
      overlays = toList overlays';
    in ''
      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 2>/dev/null || true)
        # skip files without `compatible` string
        test -z "$dtbCompat" && continue

        ${flip (concatMapStringsSep "\n") overlays (o: ''
        overlayCompat="$(fdtget -t s "${o.dtboFile}" / compatible)"

        # skip incompatible and non-matching overlays
        if [[ ! "$dtbCompat" =~ "$overlayCompat" ]]; then
          echo "Skipping overlay ${o.name}: incompatible with $(basename "$dtb")"
        elif ${if (o.filter == null) then "false" else ''
          [[ "''${dtb//${o.filter}/}" ==  "$dtb" ]]
        ''}
        then
          echo "Skipping overlay ${o.name}: filter does not match $(basename "$dtb")"
        else
          echo -n "Applying overlay ${o.name} to $(basename "$dtb")... "
          mv "$dtb"{,.in}
          fdtoverlay -o "$dtb" -i "$dtb.in" "${o.dtboFile}"
          echo "ok"
          rm "$dtb.in"
        fi
        '')}

      done
    '';
  });
}