#!/bin/sh
# Build a kernel's boot slot (uzImage.bin + scriptcmd) and rotate the old slot to rollback
# $1: version (default: newest installed)
set -e

boot=/boot/uboot
template=/usr/share/wmt-boot/uboot.cmd

# Skip the mount check in the build chroot (no systemd); on a device the FAT must be mounted
if [ -d /run/systemd/system ] && ! mountpoint -q "$boot"; then
	echo "wmt-deploy-boot: $boot is not mounted; refusing to write the boot slot" >&2
	exit 1
fi

version=${1:-$(ls -t /boot/vmlinuz-* 2>/dev/null | head -n1 | sed 's#.*/vmlinuz-##')}
image="/boot/vmlinuz-$version"
[ -n "$version" ] && [ -f "$image" ] || exit 0

dtb=$(find "/usr/lib/linux-image-$version" -name 'wm8505-ref.dtb' 2>/dev/null)
[ -n "$dtb" ] || exit 0

# The kernel deb's Version is the bare build stamp; render it as the splash's UTC build time
stamp=$(dpkg-query -W -f='${Version}' "linux-image-$version")
build_time=$(date -u -d "@$stamp" +"%Y-%m-%d %H:%M:%S UTC")

# Optional user-supplied kernel arguments
EXTRA_CMDLINE=
[ -f /etc/default/wmt-boot ] && . /etc/default/wmt-boot

# Stage on the FAT: keeps the final swap an in-filesystem rename
new="$boot/.script.new"
rm -rf "$new"
mkdir "$new"

# uzImage.bin: zImage with its DTB appended, wrapped as a U-Boot kernel image
cat "$image" "$dtb" > "$new/.payload"
mkimage -A arm -O linux -T kernel -C none -a 0x8000 -e 0x8000 -n linux-wmt \
	-d "$new/.payload" "$new/uzImage.bin" >/dev/null

{
	printf 'setenv KERNEL_RELEASE %s\n' "$version"
	printf 'setenv BUILD_TIME %s\n' "$build_time"
	printf 'setenv EXTRA_CMDLINE %s\n' "$EXTRA_CMDLINE"
	cat "$template"
} > "$new/.payload"
mkimage -A arm -O linux -T script -C none -a 1 -e 0 -n "WMT OS boot script" \
	-d "$new/.payload" "$new/scriptcmd" >/dev/null
rm "$new/.payload"

printf '%s\n' "$version" > "$new/version"
sync

# Demote the active slot to rollback only if it holds a different, still-installed kernel
active=$(cat "$boot/script/version" 2>/dev/null || true)
if [ -d "$boot/script" ] && [ "$active" != "$version" ] && [ -f "/boot/vmlinuz-$active" ]; then
	rm -rf "$boot/script.bak"
	mv "$boot/script" "$boot/script.bak"
else
	rm -rf "$boot/script"
fi
mv "$new" "$boot/script"
# Drop the rollback slot if it now duplicates the active kernel
if [ "$(cat "$boot/script.bak/version" 2>/dev/null)" = "$version" ]; then
	rm -rf "$boot/script.bak"
fi
sync
