Merge pull request #1945 from JamieMagee/fix/raspberry-pi-firmware-cross
raspberry-pi: fix cross-compiled SD images
This commit is contained in:
commit
fccfa9031a
1 changed files with 69 additions and 63 deletions
|
|
@ -24,81 +24,87 @@ let
|
||||||
|
|
||||||
# install-rpi-firmware <target-dir>
|
# install-rpi-firmware <target-dir>
|
||||||
# Idempotent: copies via temp file + rename, and prunes stale DTBs/overlays.
|
# Idempotent: copies via temp file + rename, and prunes stale DTBs/overlays.
|
||||||
installScript = pkgs.writeShellApplication {
|
mkInstallScript =
|
||||||
name = "install-rpi-firmware";
|
scriptPkgs:
|
||||||
runtimeInputs = [ pkgs.coreutils ];
|
scriptPkgs.writeShellApplication {
|
||||||
text = ''
|
name = "install-rpi-firmware";
|
||||||
target="$1"
|
runtimeInputs = [ scriptPkgs.coreutils ];
|
||||||
shopt -s nullglob
|
text = ''
|
||||||
|
target="$1"
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
firmwareBoot=${cfg.package}/share/raspberrypi/boot
|
firmwareBoot=${cfg.package}/share/raspberrypi/boot
|
||||||
${
|
${
|
||||||
if cfg.useGenerationDeviceTree then
|
if cfg.useGenerationDeviceTree then
|
||||||
''
|
''
|
||||||
# Prefer the booted generation's device trees over the vendor ones.
|
# Prefer the booted generation's device trees over the vendor ones.
|
||||||
dtbSrc=/run/current-system/dtbs
|
dtbSrc=/run/current-system/dtbs
|
||||||
[ -d "$dtbSrc" ] || dtbSrc=$firmwareBoot
|
[ -d "$dtbSrc" ] || dtbSrc=$firmwareBoot
|
||||||
''
|
''
|
||||||
else
|
else
|
||||||
''
|
''
|
||||||
dtbSrc=$firmwareBoot
|
dtbSrc=$firmwareBoot
|
||||||
''
|
''
|
||||||
}
|
}
|
||||||
|
|
||||||
mkdir -p "$target/overlays"
|
mkdir -p "$target/overlays"
|
||||||
|
|
||||||
# Copy via a temp file then rename so an interrupted run can't leave a
|
# Copy via a temp file then rename so an interrupted run can't leave a
|
||||||
# half-written file behind. The firmware partition is FAT, so the rename
|
# half-written file behind. The firmware partition is FAT, so the rename
|
||||||
# isn't truly atomic, but it still beats a partial copy when the
|
# isn't truly atomic, but it still beats a partial copy when the
|
||||||
# activation script rewrites the partition on a live system.
|
# activation script rewrites the partition on a live system.
|
||||||
copyForced() {
|
copyForced() {
|
||||||
cp "$1" "$2.tmp"
|
cp "$1" "$2.tmp"
|
||||||
mv "$2.tmp" "$2"
|
mv "$2.tmp" "$2"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Track every file we copy this run, keyed by destination path, so the
|
# Track every file we copy this run, keyed by destination path, so the
|
||||||
# prune step below can delete stale device trees / overlays left behind
|
# prune step below can delete stale device trees / overlays left behind
|
||||||
# by a previous generation.
|
# by a previous generation.
|
||||||
declare -A kept
|
declare -A kept
|
||||||
|
|
||||||
echo "rpi-firmware: copying device trees from $dtbSrc"
|
echo "rpi-firmware: copying device trees from $dtbSrc"
|
||||||
for dtb in "$dtbSrc"/*.dtb "$dtbSrc"/broadcom/*.dtb; do
|
for dtb in "$dtbSrc"/*.dtb "$dtbSrc"/broadcom/*.dtb; do
|
||||||
dst="$target/$(basename "$dtb")"
|
dst="$target/$(basename "$dtb")"
|
||||||
copyForced "$dtb" "$dst"
|
copyForced "$dtb" "$dst"
|
||||||
kept[$dst]=1
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -d "$dtbSrc/overlays" ]; then
|
|
||||||
for ovr in "$dtbSrc"/overlays/*; do
|
|
||||||
dst="$target/overlays/$(basename "$ovr")"
|
|
||||||
copyForced "$ovr" "$dst"
|
|
||||||
kept[$dst]=1
|
kept[$dst]=1
|
||||||
done
|
done
|
||||||
fi
|
|
||||||
|
|
||||||
# Prune stale device trees / overlays.
|
if [ -d "$dtbSrc/overlays" ]; then
|
||||||
for fn in "$target"/*.dtb "$target"/overlays/*; do
|
for ovr in "$dtbSrc"/overlays/*; do
|
||||||
if [ "''${kept[$fn]:-}" != 1 ]; then
|
dst="$target/overlays/$(basename "$ovr")"
|
||||||
rm -v -- "$fn"
|
copyForced "$ovr" "$dst"
|
||||||
|
kept[$dst]=1
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
done
|
|
||||||
|
|
||||||
echo "rpi-firmware: copying GPU boot code"
|
# Prune stale device trees / overlays.
|
||||||
for src in "$firmwareBoot"/bootcode.bin "$firmwareBoot"/start*.elf "$firmwareBoot"/fixup*.dat; do
|
for fn in "$target"/*.dtb "$target"/overlays/*; do
|
||||||
copyForced "$src" "$target/$(basename "$src")"
|
if [ "''${kept[$fn]:-}" != 1 ]; then
|
||||||
done
|
rm -v -- "$fn"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
${lib.optionalString cfg.uboot.enable ''
|
echo "rpi-firmware: copying GPU boot code"
|
||||||
echo "rpi-firmware: copying U-Boot"
|
for src in "$firmwareBoot"/bootcode.bin "$firmwareBoot"/start*.elf "$firmwareBoot"/fixup*.dat; do
|
||||||
copyForced ${cfg.uboot.package}/u-boot.bin "$target/u-boot.bin"
|
copyForced "$src" "$target/$(basename "$src")"
|
||||||
''}
|
done
|
||||||
|
|
||||||
echo "rpi-firmware: copying config.txt"
|
${lib.optionalString cfg.uboot.enable ''
|
||||||
copyForced ${config.hardware.raspberry-pi.configtxt.file} "$target/config.txt"
|
echo "rpi-firmware: copying U-Boot"
|
||||||
|
copyForced ${cfg.uboot.package}/u-boot.bin "$target/u-boot.bin"
|
||||||
|
''}
|
||||||
|
|
||||||
echo "rpi-firmware: done ($target)"
|
echo "rpi-firmware: copying config.txt"
|
||||||
'';
|
copyForced ${config.hardware.raspberry-pi.configtxt.file} "$target/config.txt"
|
||||||
};
|
|
||||||
|
echo "rpi-firmware: done ($target)"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Target tools for activation, build tools for images.
|
||||||
|
installScript = mkInstallScript pkgs;
|
||||||
|
imageInstallScript = mkInstallScript pkgs.buildPackages;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.hardware.raspberry-pi.firmware = {
|
options.hardware.raspberry-pi.firmware = {
|
||||||
|
|
@ -189,7 +195,7 @@ in
|
||||||
# sd-image module is imported. mkForce so we override (not merge with)
|
# sd-image module is imported. mkForce so we override (not merge with)
|
||||||
# sd-image-aarch64.nix, which also sets this and would clobber config.txt.
|
# sd-image-aarch64.nix, which also sets this and would clobber config.txt.
|
||||||
(lib.optionalAttrs (options ? sdImage) {
|
(lib.optionalAttrs (options ? sdImage) {
|
||||||
sdImage.populateFirmwareCommands = lib.mkForce "${lib.getExe installScript} ./firmware\n";
|
sdImage.populateFirmwareCommands = lib.mkForce "${lib.getExe imageInstallScript} ./firmware\n";
|
||||||
})
|
})
|
||||||
(lib.mkIf cfg.enable {
|
(lib.mkIf cfg.enable {
|
||||||
system.activationScripts.raspberry-pi-firmware = lib.stringAfter [ "specialfs" ] ''
|
system.activationScripts.raspberry-pi-firmware = lib.stringAfter [ "specialfs" ] ''
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue