#! @bash@/bin/sh -e shopt -s nullglob export PATH=/empty for i in @path@; do PATH=$PATH:$i/bin; done usage() { echo "usage: $0 -c [-d ] [-g ]" >&2 exit 1 } default= # Default configuration target=/boot # Target directory numGenerations=0 # Number of other generations to include in the menu while getopts "c:d:g:" opt; do case "$opt" in c) default="$OPTARG" ;; d) target="$OPTARG" ;; g) numGenerations="$OPTARG" ;; \?) usage ;; esac done [ "$default" = "" ] && usage mkdir -p $target/nixos # Convert a path to a file in the Nix store such as # /nix/store/-/file to --. cleanName() { local path="$1" echo "$path" | sed 's|^/nix/store/||' | sed 's|/|-|g' } # Copy a file from the Nix store to $target/nixos. declare -A filesCopied copyToKernelsDir() { local src=$(readlink -f "$1") local dst="$target/nixos/$(cleanName $src)" # Don't copy the file if $dst already exists. This means that we # have to create $dst atomically to prevent partially copied # kernels or initrd if this script is ever interrupted. if ! test -e $dst; then local dstTmp=$dst.tmp.$$ cp -r $src $dstTmp mv $dstTmp $dst fi filesCopied[$dst]=1 result=$dst } # Copy its kernel, initrd and dtbs to $target/nixos, and echo out an # extlinux menu entry addEntry() { local path=$(readlink -f "$1") local tag="$2" # Generation number or 'default' if ! test -e $path/kernel -a -e $path/initrd; then return fi copyToKernelsDir "$path/kernel"; kernel=$result copyToKernelsDir "$path/initrd"; initrd=$result dtbDir=$(readlink -m "$path/dtbs") if [ -e "$dtbDir" ]; then copyToKernelsDir "$dtbDir"; dtbs=$result fi timestampEpoch=$(stat -L -c '%Z' $path) timestamp=$(date "+%Y-%m-%d %H:%M" -d @$timestampEpoch) nixosLabel="$(cat $path/nixos-version)" extraParams="$(cat $path/kernel-params)" filesCopied[$target/nixos/$tag]=1 echo > $target/nixos/$tag.tmp echo "ext4load usb 0:2 \$kernel_addr_r boot/nixos/$(basename $kernel)" >> $target/nixos/$tag.tmp echo "ext4load usb 0:2 \$fdt_addr_r boot/nixos/$(basename $dtbs)/marvell/armada-7040-mochabin.dtb" >> $target/nixos/$tag.tmp echo "ext4load usb 0:2 0xa700000 boot/nixos/$(basename $initrd)" >> $target/nixos/$tag.tmp echo "setenv bootargs \$console init=$path/init $extraParams" >> $target/nixos/$tag.tmp echo "booti \$kernel_addr_r 0xa700000:\$filesize \$fdt_addr_r" >> $target/nixos/$tag.tmp mkimage -A arm64 -O u-boot -T script -C none -a 0 -e 0 -n "Boot Script ${nixosLabel} ${timestamp}" -d $target/nixos/$tag.tmp $target/nixos/$tag } addEntry $default default if [ "$numGenerations" -gt 0 ]; then # Add up to $numGenerations generations of the system profile to the menu, # in reverse (most recent to least recent) order. for generation in $( (cd /nix/var/nix/profiles && ls -d system-*-link) \ | sed 's/system-\([0-9]\+\)-link/\1/' \ | sort -n -r \ | head -n $numGenerations); do link=/nix/var/nix/profiles/system-$generation-link addEntry $link $generation done fi # Remove obsolete files from $target/nixos. for fn in $target/nixos/*; do if ! test "${filesCopied[$fn]}" = 1; then echo "Removing no longer needed boot file: $fn" chmod +w -- "$fn" rm -rf -- "$fn" fi done