#!/bin/sh
# vim:ts=2:sw=2:et
# see also:
# https://kernel-handbook.alioth.debian.org/ch-update-hooks.html#s-kernel-hooks

set -e

# Play nice when run under debconf.
exec </dev/null >&2

eval set -- "$DEB_MAINT_PARAMS"

# Only run on configure and remove to avoid unnecessary work.
case "$1" in
  configure|remove)
    ;;
  *)
    exit 0
    ;;
esac

if ischroot ; then
  true # chroot detected - skip mount point check
elif test -e /usr/bin/systemd-detect-virt && systemd-detect-virt -q ; then
  true # virtualization detected - skip mount point check
elif ! mountpoint -q /boot/firmware; then
  echo "raspi3-firmware: missing /boot/firmware, did you forget to mount it?" >&2
  exit 1
fi

# Ensure the target directory exists. See https://bugs.debian.org/887062
mkdir -p /boot/firmware

latest_kernel=$(ls -1 /boot/vmlinuz-* | grep -v '\.dpkg-bak$' | sort -V -r | head -1)
if [ -z "$latest_kernel" ]; then
  echo "raspi3-firmware: no kernel found in /boot/vmlinuz-*, cannot populate /boot/firmware"
  exit 0
fi

latest_initrd=$(ls -1 /boot/initrd.img-* | grep -v '\.dpkg-bak$' | sort -V -r | head -1)
if [ -z "$latest_initrd" ]; then
  echo "raspi3-firmware: no initrd found in /boot/initrd.img-*, cannot populate /boot/firmware"
  exit 0
fi

# Default configurations, overridable at /etc/default/raspi3-firmware
CMA=64M
ROOTPART=/dev/mmcblk0p2
KERNEL="auto"
INITRAMFS="auto"
CONSOLES="auto"
if [ -r /etc/default/raspi3-firmware ]; then
        . /etc/default/raspi3-firmware
fi

# copy and rename the available device tree binaries
# the bootloader will pick the right device tree binary
# if it is named according to the system on chip family name
arch=$(dpkg --print-architecture)
if [ "arm64" = "$arch" ]; then
  dtb_path="/usr/lib/linux-image-${latest_kernel#/boot/vmlinuz-}/broadcom"
else
  # there is no vendor subdirectory for armhf
  dtb_path="/usr/lib/linux-image-${latest_kernel#/boot/vmlinuz-}"
fi

if [ "$KERNEL" = "auto" ]; then
  pi0w_dtb=${dtb_path}/bcm2835-rpi-zero-w.dtb
  pi1ap_dtb=${dtb_path}/bcm2835-rpi-a-plus.dtb
  pi1bp_dtb=${dtb_path}/bcm2835-rpi-b-plus.dtb
  pi2b_dtb=${dtb_path}/bcm2836-rpi-2-b.dtb
  pi3b_dtb=${dtb_path}/bcm2837-rpi-3-b.dtb
  pi3bp_dtb=${dtb_path}/bcm2837-rpi-3-b-plus.dtb

  [ -e "${pi0w_dtb}"  ] && cp "${pi0w_dtb}"  /boot/firmware/bcm2835-rpi-zero-w.dtb
  [ -e "${pi1ap_dtb}"  ] && cp "${pi1ap_dtb}" /boot/firmware/bcm2835-rpi-a-plus.dtb
  [ -e "${pi1bp_dtb}"  ] && cp "${pi1bp_dtb}" /boot/firmware/bcm2835-rpi-b-plus.dtb
  [ -e "${pi2b_dtb}"  ] && cp "${pi2b_dtb}"  /boot/firmware/bcm2709-rpi-2-b.dtb
  [ -e "${pi3b_dtb}"  ] && cp "${pi3b_dtb}"  /boot/firmware/bcm2710-rpi-3-b.dtb
  [ -e "${pi3bp_dtb}" ] && cp "${pi3bp_dtb}" /boot/firmware/bcm2710-rpi-3-b-plus.dtb

  latest_kernel_basename=$(basename "$latest_kernel")
  latest_initrd_basename=$(basename "$latest_initrd")
  KERNEL=${latest_kernel_basename}

  cp "$latest_kernel" /boot/firmware/
  cp "$latest_initrd" /boot/firmware/

  if [ "$CONSOLES" = "auto" ]; then
    serial="ttyAMA0,115200"
    kernelmajor=$(echo "${latest_kernel_basename}" | sed 's,^vmlinuz-,,g' | cut -d. -f 1)
    kernelminor=$(echo "${latest_kernel_basename}" | cut -d. -f 2)
    if [ $kernelmajor -ge 4 ]; then
      if [ $kernelminor -ge 14 ]; then
        # Since Linux 4.14, /dev/ttyS1 is the UART on the pinheader.
        serial="ttyS1,115200"
      fi
    fi
  fi
fi



# Truncate the config.txt file so that we start with a blank slate
echo >/boot/firmware/config.txt

if [ "$arch" = "arm64" ]; then
  cat >/boot/firmware/config.txt <<EOF
# Switch the CPU from ARMv7 into ARMv8 (aarch64) mode
arm_64bit=1

EOF
fi

cat >>/boot/firmware/config.txt <<EOF
enable_uart=1

kernel=${KERNEL}
EOF

if [ "$INITRAMFS" != "no" ]; then
  cat >>/boot/firmware/config.txt <<EOF
# For details on the initramfs directive, see
# https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=10532
initramfs ${latest_initrd_basename}
EOF
fi


# Our cmdline.txt is the default (see http://elinux.org/RPi_cmdline.txt), but
# without parameters for drivers we do not have (e.g. dwc_otg.lpm_enable) or
# parameters we do not need (e.g. rootfstype=, as we are using an initrd).
# We leave the consoles configurable.

pre_cmdline="console=tty0 console=${serial}"

if [ "$CONSOLES" != "auto" ]; then
  pre_cmdline=""
  for console in $CONSOLES; do
    pre_cmdline="${pre_cmdline} console=${console}"
  done
fi

cat >/boot/firmware/cmdline.txt <<EOF
${pre_cmdline} root=$ROOTPART rw elevator=deadline fsck.repair=yes net.ifnames=0 cma=$CMA rootwait
EOF

cd /boot/firmware
for file in vmlinuz-* initrd.img-*; do
  if [ ! -e "/boot/$file" ]; then
    echo "raspi3-firmware: deleting obsolete /boot/firmware/$file (no longer in /boot)"
    # Keep going if cleanup of individual files fails. It is better for the end
    # user to have a working package upgrade and a slight waste of space than a
    # broken upgrade.
    rm -f "$file" || true
  fi
done
