diff options
-rw-r--r-- | package/fwupdate/Makefile | 28 | ||||
-rw-r--r-- | package/fwupdate/files/fwupdate.init | 27 | ||||
-rw-r--r-- | package/fwupdate/files/fwupdate.service | 9 | ||||
-rwxr-xr-x | package/fwupdate/src/fwupdate | 137 | ||||
-rwxr-xr-x | package/fwupdate/src/fwvalidate | 132 |
5 files changed, 333 insertions, 0 deletions
diff --git a/package/fwupdate/Makefile b/package/fwupdate/Makefile new file mode 100644 index 000000000..2677dc818 --- /dev/null +++ b/package/fwupdate/Makefile @@ -0,0 +1,28 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include $(ADK_TOPDIR)/rules.mk + +PKG_NAME:= fwupdate +PKG_VERSION:= 1.0 +PKG_RELEASE:= 1 +PKG_DESCR:= update firmware +PKG_SECTION:= sys/misc +PKG_URL:= http://www.openadk.org + +NO_DISTFILES:= 1 + +include $(ADK_TOPDIR)/mk/package.mk + +$(eval $(call PKG_template,FWUPDATE,fwupdate,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) + +CONFIG_STYLE:= manual +BUILD_STYLE:= manual +INSTALL_STYLE:= manual + +fwupdate-install: + $(INSTALL_DIR) $(IDIR_FWUPDATE)/usr/sbin + $(INSTALL_BIN) $(WRKBUILD)/fwupdate $(IDIR_FWUPDATE)/usr/sbin + $(INSTALL_BIN) $(WRKBUILD)/fwvalidate $(IDIR_FWUPDATE)/usr/sbin + +include ${ADK_TOPDIR}/mk/pkg-bottom.mk diff --git a/package/fwupdate/files/fwupdate.init b/package/fwupdate/files/fwupdate.init new file mode 100644 index 000000000..bf7047796 --- /dev/null +++ b/package/fwupdate/files/fwupdate.init @@ -0,0 +1,27 @@ +#!/bin/sh +#PKG fwupdate +#INIT 99 + +. /etc/rc.conf + +case $1 in +autostop) ;; +autostart) + test x"${fwupdate:-NO}" = x"NO" && exit 0 + test x"$fwupdate" = x"DAEMON" && test -x /bin/mksh && exec mksh -T- $0 start + exec sh $0 start + ;; +start) + /usr/sbin/fwvalidate + ;; +stop) + ;; +restart) + sh $0 stop + sh $0 start + ;; +*) + echo "usage: $0 (start|stop|restart)" + exit 1 +esac +exit $? diff --git a/package/fwupdate/files/fwupdate.service b/package/fwupdate/files/fwupdate.service new file mode 100644 index 000000000..f54519547 --- /dev/null +++ b/package/fwupdate/files/fwupdate.service @@ -0,0 +1,9 @@ +[Unit] +Description=Firmware Update Validation +After=dropbear.service + +[Service] +ExecStart=/usr/sbin/fwvalidate + +[Install] +WantedBy=multi-user.target diff --git a/package/fwupdate/src/fwupdate b/package/fwupdate/src/fwupdate new file mode 100755 index 000000000..7a73115e0 --- /dev/null +++ b/package/fwupdate/src/fwupdate @@ -0,0 +1,137 @@ +#!/bin/sh +# This file is part of the OpenADK project. +# Do update. + +PART0="/dev/sda2" +PART1="/dev/sda3" + +# Name of the archive, which is the firmware. For this file is the checksum calculated and +# checked against the one from the tar archive. +FW_NAME="openadk.tar.xz" +CHECK_SUM_FILE="sha256.txt" +TMP_MOUNT="/mnt" + +if [ -z $1 ]; then + echo "Usage: $0 <full path to update filename>" + exit 1 +fi +if [ ! -f $1 ]; then + echo "File $1 not found" + exit 1 +fi +FIRMWARE=$1 + +echo "Validate new firmware $FIRMWARE" +echo "Extract checksum file ..." +cmd="tar -xf $FIRMWARE $CHECK_SUM_FILE" +$cmd +if [ ! -f $CHECK_SUM_FILE ];then + echo "No checksum file found! $CHECK_SUM_FILE" + exit 3 +fi + +if [ $(wc -m $CHECK_SUM_FILE | cut -d\ -f1) -eq 65 ];then + echo "Found a checksum in file $CHECK_SUM_FILE" +else + echo "No checksum found in archive! $(wc -m $CHECK_SUM_FILE | cut -d\ -f1)" + exit 4 +fi + +CHECK_SUM_UPDATE_FILE="$(cat $CHECK_SUM_FILE)" + +echo "Calculate the checksum of the new firmware ..." +CHECK_SUM_NEW_SYSTEM=$(tar -xf $FIRMWARE $FW_NAME -O | sha256sum - |cut -d\ -f1) + +echo "Compare the checksums ..." +if [ "X$CHECK_SUM_NEW_SYSTEM" = "X$CHECK_SUM_UPDATE_FILE" ]; then + echo "Checksum verified (they match): " +else + echo "Checksum does not match!" + echo "${CHECK_SUM_UPDATE_FILE} " + echo "${CHECK_SUM_NEW_SYSTEM}" +fi + +echo "First unmount $TMP_MOUNT the spare partition just in case ..." +umount $TMP_MOUNT 2>/dev/null + +# create the mkfs options depending on which is the active partition +CURRENT_SYS="$(rdev /|awk '{ print $1 }')" +case "$CURRENT_SYS" in + "$PART0") + MOUNTPART="$PART1" + OS=OpenADK2 + ;; + "$PART1") + MOUNTPART="$PART0" + OS=OpenADK1 + ;; + *) + echo "Current partition $CURRENT_SYS not recognized" + exit 5 + ;; +esac +echo "Currently the system is running on $CURRENT_SYS" + +# Create filesystem on inactive partition +echo "The partition $MOUNTPART is going to be prepared for the new system." +echo "Creating the filesystem ..." + +mkfs.ext2 -j -q -F $MOUNTPART +if [ $? -ne 0 ];then + echo "It was not possible to create the new filesystem on $MOUNTPART" + exit 6 +fi + +echo "Mount the new partition $MOUNTPART ..." +mount -t ext4 $MOUNTPART $TMP_MOUNT +if [ $? -ne 0 ];then + echo "It was not possible to mount the partition for the new system!" + echo "Please reboot the system and try to update again." + exit 7 +fi + +cd $TMP_MOUNT +echo "The new system is going to be extracted into the partition $MOUNTPART ..." +tar -xf $FIRMWARE $FW_NAME -O|tar -xJf - +if [ $? -ne 0 ]; then + echo "The extraction of the new system failed!" + echo "Please reboot the system and try to update again." + cd / + umount $MOUNTPART + exit 8 +fi + +echo "Checking the new system on next boot" +touch $TMP_MOUNT/firmware_check +if [ $? -ne 0 ]; then + echo "General ERROR" + echo "Please reboot the system and try to update again." + cd / + umount $MOUNTPART + exit 9 +fi +# echo "DD.MM.YYYY hh:mm:hh\n$(date '+%d.%m.%Y %H:%M:%S')" > install_date.txt +date '+%d.%B.%Y %H:%M:%S' > $TMP_MOUNT/installation_date.txt +if [ $? -ne 0 ]; then + echo "General ERROR" + echo "Please reboot the system and try to update again." + cd / + umount $MOUNTPART + exit 9 +fi +echo "$CHECK_SUM_NEW_FW" >> $TMP_MOUNT/installation_date.txt +if [ $? -ne 0 ]; then + echo "General ERROR" + echo "Please reboot the system and try to update again." + cd / + umount $MOUNTPART + exit 9 +fi + +cd / +umount $MOUNTPART +mount -o remount,rw /boot +grub-reboot $OS +mount -o remount,ro /boot +sync +echo "Reboot now to the updated system $OS" diff --git a/package/fwupdate/src/fwvalidate b/package/fwupdate/src/fwvalidate new file mode 100755 index 000000000..e87c5beed --- /dev/null +++ b/package/fwupdate/src/fwvalidate @@ -0,0 +1,132 @@ +#!/bin/sh +# This file is part of the OpenADK project. +# Validate update. + +PART0="/dev/sda2" +PART1="/dev/sda3" + +APPLIANCE_NAME=OpenADK + +BOOT0_NAME="OpenADK1" +BOOT1_NAME="OpenADK2" + +CURRENT_SYS="$(rdev /|awk '{ print $1 }' )" +TIMEOUT=45 +STAT_FILE="/tmp/update_status" + +SSH_KEY_FOLDER=/etc/dropbear/ +SSH_KEYS=("dropbear_dss_host_key" "dropbear_ecdsa_host_key" "dropbear_rsa_host_key") + +DEBUG=1 + +if [ "x$1" == "xtest" ];then + TIMEOUT=1 +fi + +get_interface(){ + ip route list | grep '^default' | cut -d\ -f 5 +} +get_nw_mask(){ + # This function will get the NW Mask in the form /x e.g. /16 + local BIT=$(ip a s $(get_interface)| grep inet\ | cut -d/ -f2| cut -d\ -f1) + echo $BIT +} + +getip() { + DEFDEVICE=$(ip route list | grep ^default | cut -d\ -f5) + IPADDR=$(ip a s $(ip route list | grep ^default | cut -d\ -f5) | grep inet\ | grep 'inet' | cut -d\ -f 6 | cut -d/ -f1) + echo $IPADDR +} + +chk_initial_save(){ + if [ $(cfgfs status | wc -l) -gt 0 ];then + echo "please save configuration" + fi +} +updategrub(){ + + mount -o remount,rw /boot + + case "$CURRENT_SYS" in + "$PART1") + grub-set-default OpenADK2 + ;; + "$PART0") + grub-set-default OpenADK1 + ;; + *) + echo "Current partition $CURRENT_SYS not recognized" + exit 1 + ;; + esac + + sync + mount -o remount,ro /boot + +} + +base_check() { + NET_PROGS="$(netstat -tulpn 2>/dev/null)" + TESTS=0 + TESTSUM=0 + + #test start: check if dropbear is running + T_NAME=dropbear + if [[ $NET_PROGS = *"/dropbear"* ]];then + logger -t update "check $T_NAME OK" + TESTS=$(( $TESTS + 1 )) + else + logger -t update "check $T_NAME FAILURE" + fi + ((TESTSUM = TESTSUM +1)) + #test end +} + +if [ -f /installation_date.txt ];then + echo "Update was applied at:" > $STAT_FILE + echo "$(head -n1 /installation_date.txt)" >> $STAT_FILE +else + rm -f $STAT_FILE +fi + +# Do some checks before setting the new partiton as default boot partition. +if ( [ -f /firmware_check ] || [ "x$1" = "xtest" ] );then + logger -t update "check now!" + base_check + i=0 + while [ $TESTS -lt $TESTSUM ];do + base_check + [ $DEBUG -gt 0 ] && echo "$i Only $TESTS from $TESTSUM are passed wait until $TIMEOUT" + sleep 1 + i=$(( $i + 1 )) + if [ $i -ge $TIMEOUT ];then + break + fi + done +else + logger -t update "$APPLIANCE_NAME validate nothing to do..." + if [ -f $STAT_FILE ];then + echo "Last update was successful" >> $STAT_FILE + else + echo "Firmware check was successful" >> $STAT_FILE + fi + + n=0 + chk_initial_save + exit 0 +fi + +if [ $TESTS -eq $TESTSUM ]; then + logger -t update "All Tests passed." + if [ "x$1" = "x" ]; then + logger -t update "Set default boot partition for bootloader." + rm /firmware_check + echo "System check was successful" >> $STAT_FILE + updategrub + fi +else + logger -t update "Not all tests passed. The the default system remains on the current partition." + logger -t update "Please try to reboot the system and repeat the update." + echo "ERROR last system update failed, please reboot and try again." >> $STAT_FILE + exit 1 +fi |