summaryrefslogtreecommitdiff
path: root/package/fwupdate
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@openadk.org>2017-02-05 14:48:23 +0100
committerWaldemar Brodkorb <wbx@openadk.org>2017-02-05 14:48:23 +0100
commitcd539adc4a30ce1aa659bf22490381be764de403 (patch)
tree247c421385d84191e7263c54a6ab5ea9d98cb857 /package/fwupdate
parenta2de584c87368c0d966dd9250c212a8460158b3b (diff)
add initial fwupdate application
Diffstat (limited to 'package/fwupdate')
-rw-r--r--package/fwupdate/Makefile28
-rw-r--r--package/fwupdate/files/fwupdate.init27
-rw-r--r--package/fwupdate/files/fwupdate.service9
-rwxr-xr-xpackage/fwupdate/src/fwupdate137
-rwxr-xr-xpackage/fwupdate/src/fwvalidate132
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