|
| 1 | +# Modification of nixpkgs deviceTree.applyOverlays to resolve https://github.com/NixOS/nixpkgs/issues/125354. |
| 2 | +# |
| 3 | +# Derived from https://github.com/NixOS/nixpkgs/blob/916ca8f2b0c208def051f8ea9760c534a40309db/pkgs/os-specific/linux/device-tree/default.nix. |
| 4 | +# |
| 5 | +# This replaces the default device tree overlay application process |
| 6 | +# to use `dtmerge` from `libraspberrypi`. The default overlay |
| 7 | +# application process can be problematic on Raspberry Pis due to |
| 8 | +# (among other things) issues like this: |
| 9 | +# |
| 10 | +# https://github.com/raspberrypi/firmware/issues/1718 |
| 11 | +# |
| 12 | +# and `fdtget`-based compatibility checks, which yield false |
| 13 | +# negatives (overlay is compatible, but the check says it is not): |
| 14 | +# |
| 15 | +# $ dtbCompat="$(fdtget -t s ./boot/bcm2710-rpi-3-b-plus.dtb / compatible | tee /dev/stderr)" |
| 16 | +# raspberrypi,3-model-b-plus brcm,bcm2837 |
| 17 | +# $ overlayCompat="$(fdtget -t s ./boot/overlays/disable-bt.dtbo / compatible | tee /dev/stderr)" |
| 18 | +# brcm,bcm2835 |
| 19 | +# $ [[ "$dtbCompat" =~ "$overlayCompat" ]] ; echo "$?" |
| 20 | +# 1 |
| 21 | +# |
| 22 | +# The upstream/default merging logic is here: |
| 23 | +# |
| 24 | +# https://github.com/NixOS/nixpkgs/blob/c999f2e369508fca13646ca5a0fb926b3ce0063e/pkgs/os-specific/linux/device-tree/default.nix#L27-L65 |
| 25 | +# |
| 26 | +# The `nixos-hardware` override is here: |
| 27 | +# |
| 28 | +# https://github.com/NixOS/nixos-hardware/blob/33a97b5814d36ddd65ad678ad07ce43b1a67f159/raspberry-pi/4/pkgs-overlays.nix#L5 |
| 29 | +final: prev: { |
| 30 | + deviceTree = |
| 31 | + prev.deviceTree |
| 32 | + // { |
| 33 | + applyOverlays = base: overlays': |
| 34 | + final.stdenvNoCC.mkDerivation { |
| 35 | + name = "device-tree-overlays"; |
| 36 | + nativeBuildInputs = with final; [dtc libraspberrypi]; |
| 37 | + buildCommand = let |
| 38 | + overlays = final.lib.toList overlays'; |
| 39 | + in '' |
| 40 | + mkdir -p $out |
| 41 | + cd "${base}" |
| 42 | + find . -type f -name '*.dtb' -print0 \ |
| 43 | + | xargs -0 cp -v --no-preserve=mode --target-directory "$out" --parents |
| 44 | +
|
| 45 | + for dtb in $(find "$out" -type f -name '*.dtb'); do |
| 46 | + dtbCompat=$(fdtget -t s "$dtb" / compatible 2>/dev/null || true) |
| 47 | + # skip files without `compatible` string |
| 48 | + test -z "$dtbCompat" && continue |
| 49 | +
|
| 50 | + ${final.lib.concatMapStringsSep "\n" (o: '' |
| 51 | + overlayCompat="$(fdtget -t s "${o.dtboFile}" / compatible)" |
| 52 | +
|
| 53 | + # skip incompatible and non-matching overlays |
| 54 | + if ! { [[ "$dtbCompat" =~ "$overlayCompat" ]] || [[ "$overlayCompat" = brcm,bcm2835 ]]; }; then |
| 55 | + echo "Skipping overlay ${o.name}: incompatible with $(basename "$dtb")" |
| 56 | + elif ${ |
| 57 | + if ((o.filter or null) == null) |
| 58 | + then "false" |
| 59 | + else '' |
| 60 | + [[ "''${dtb//${o.filter}/}" == "$dtb" ]] |
| 61 | + '' |
| 62 | + } |
| 63 | + then |
| 64 | + echo "Skipping overlay ${o.name}: filter does not match $(basename "$dtb")" |
| 65 | + else |
| 66 | + echo -n "Applying overlay ${o.name} to $(basename "$dtb")... " |
| 67 | + mv "$dtb"{,.in} |
| 68 | +
|
| 69 | + # dtmerge requires a .dtbo ext for dtbo files, otherwise it adds it to the given file implicitly |
| 70 | + dtboWithExt="$TMPDIR/$(basename "${o.dtboFile}").dtbo" |
| 71 | + cp -r ${o.dtboFile} "$dtboWithExt" |
| 72 | +
|
| 73 | + dtmerge "$dtb.in" "$dtb" "$dtboWithExt" |
| 74 | +
|
| 75 | + echo "ok" |
| 76 | + rm "$dtb.in" "$dtboWithExt" |
| 77 | + fi |
| 78 | + '') |
| 79 | + overlays} |
| 80 | +
|
| 81 | + done''; |
| 82 | + }; |
| 83 | + }; |
| 84 | +} |
0 commit comments