#!/bin/sh # # OpenIPC.org | v.20220221 # set -e soc=$(fw_printenv -n soc) || (echo -e "\n\e[1;31mSOC not defined in U-Boot ENV...\e[0m\n"; exit 1) vendor=$(ipcinfo --vendor) kernel=$(awk -F ':' '/"kernel"/ {print $1}' /proc/mtd) rootfs=$(awk -F ':' '/"rootfs"/ {print $1}' /proc/mtd) overlay=$(awk -F ':' '/"rootfs_data"/ {print $1}' /proc/mtd) kernelrelease=0x$(xxd -l 4 -s 8 -p /dev/"${kernel}" | xargs) systemrelease=$(cat /etc/os-release | grep "GITHUB_VERSION" | head -1 | cut -d= -f2) github="https://github.com/OpenIPC/firmware/releases/download/latest" option="-s --connect-timeout 30 --max-time 60" stop_services() { echo -e "\n\e[1;31mForced shutdown of services...\e[0m\n" killall majestic || true killall crond klogd ntpd rngd syslogd || true } unload_modules() { echo -e "\n\e[1;31mUnload vendor specific modules...\e[0m\n" load_$vendor -r >/dev/null 2>&1 || true } check_memory() { echo -e "\n\e[1;31mCheck RAM size...\e[0m\n" free } download_firmware() { if [ $remotely -eq 1 ]; then echo -e "\n\e[1;31mDownloading the latest firmware...\e[0m\n" echo ${1} curl ${option} -L "${1}" -o - | gzip -d | tar xvf - -C /tmp || (echo -e "\n\e[1;31mError receiving the update file, execution was interrupted...\e[0m\n"; exit 1) fi } check_sum() { if [ $md5 -eq 1 ]; then cd $(dirname "${1}") md5sum -c -s "${1}.md5sum" if [ $? -eq 0 ]; then echo -e "\n\e[1;31m${2}: Checksum verified...\e[0m\n" else echo -e "\n\e[1;31m${2}: Checksum error, execution was interrupted...\e[0m\n" exit 1 fi else echo -e "\n\e[1;31m${2}: Checksum skipped...\e[0m\n" fi } check_soc() { if [ $host -eq 1 ]; then echo -e "\n\e[1;32m${2}: installed SOC: ${soc}\e[0m" echo -e "\e[1;32m${2}: new SOC: ${1}\e[0m\n" if [ "${1}" = "${soc}" ]; then echo -e "\n\e[1;31m${2}: Hostname verified...\e[0m\n" else echo -e "\n\e[1;31m${2} is not for this system, execution was interrupted...\e[0m\n" exit 1 fi else echo -e "\n\e[1;31m${2}: Hostname check skipped...\e[0m\n" fi } check_release() { if [ ${version} -eq 1 ]; then echo -e "\n\e[1;32m${3}: installed release: ${1}\e[0m" echo -e "\e[1;32m${3}: new release: ${2}\e[0m\n" if [ "${1}" = "${2}" ]; then echo -e "\n\e[1;31m${3} has the same release version, skipping...\e[0m\n" return 0 else return 1 fi else echo -e "\n\e[1;31m${3}: Release version check skipped...\e[0m\n" return 1 fi } mount_rootfs() { mkdir -p /tmp/rootfs loop=$(losetup -f) [ $? -eq 0 ] && losetup "${loop}" "${1}" && mount "${loop}" /tmp/rootfs if [ $? -eq 0 ]; then new_soc=$(cat /tmp/rootfs/etc/hostname | head -1 | cut -d- -f2) new_systemrelease=$(cat /tmp/rootfs/etc/os-release | grep "GITHUB_VERSION" | head -1 | cut -d= -f2) umount /tmp/rootfs rm -rf /tmp/rootfs losetup -d "${loop}" else if [ $host -eq 1 ]; then echo -e "\n\e[1;31mRootfs: Unable to get hostname, execution was interrupted...\e[0m\n" exit 1 fi fi } writing_kernel() { if [ $update_kernel -eq 1 ]; then check_sum "${1}" "Kernel" new_kernelrelease=0x$(xxd -l 4 -s 8 -p "${1}" | xargs) check_release "${kernelrelease}" "${new_kernelrelease}" "Kernel" && return 0 new_soc=$(od -N 32 -j 32 "${1}" -S 1 -A none | cut -d- -f3) check_soc "${new_soc}" "Kernel" echo -e "\n\e[1;31mWriting a new kernel...\e[0m\n" flashcp -v "${1}" /dev/${kernel} fi } writing_rootfs() { if [ $update_rootfs -eq 1 ]; then check_sum "${1}" "Rootfs" mount_rootfs "${1}" check_release "${systemrelease}" "${new_systemrelease}" "Rootfs" && return 0 check_soc "${new_soc}" "Rootfs" echo -e "\n\e[1;31mWriting a new rootfs...\e[0m\n" flashcp -v "${1}" /dev/${rootfs} fi } clearing_overlayfs() { if [ $clear_overlayfs -eq 1 ]; then echo -e "\n\e[1;31mСlearing the overlayfs partition...\e[0m\n" flash_eraseall -j /dev/${overlay} fi } quick_reboot() { if [ $no_reboot -eq 0 ]; then echo -e "\n\e[1;31mRebooting without any questions...\e[0m\n" sleep 1 reboot -f fi } print_usage() { echo "Usage: ./sysupgrade [-option]" echo "options:" echo "Remotely:" echo " -k update kernel" echo " -r update rootfs" echo " --url=URL URL for update file (.tgz format)" echo "Locally:" echo " --kernel=[FILE] update kernel from file (uImage format)" echo " --rootfs=[FILE] update rootfs from file (squashfs format)" echo echo " -f skip check md5 hash, release version" echo " --force and hostname" echo " -n clear overlayfs" echo " -x no reboot after success execution" echo " -h --help help information" } update_kernel=0 update_rootfs=0 clear_overlayfs=0 no_reboot=0 usage=0 from_url=0 remotely=0 locally=0 md5=1 host=1 version=1 for arg in $@ do case $arg in "-k") update_kernel=1 remotely=1 ;; "-r") update_rootfs=1 remotely=1 ;; "-n") clear_overlayfs=1 ;; "-x") no_reboot=1 ;; "-f") md5=0 version=0 ;; "-h") usage=1 ;; *) case $(echo $arg | cut -d= -f1) in "--kernel") kernel_file=$(echo =$arg | cut -d= -f3-) update_kernel=1 locally=1 ;; "--rootfs") rootfs_file=$(echo =$arg | cut -d= -f3-) update_rootfs=1 locally=1 ;; "--url") url=$(echo =$arg | cut -d= -f3-) from_url=1 remotely=1 ;; "--force") md5=0 host=0 version=0 ;; "--help") usage=1 ;; *) usage=1; ;; esac esac done if ( [ $remotely -eq 1 ] && [ $locally -eq 1 ] ) || [ $usage -eq 1 ] || \ ( [ $remotely -eq 0 ] && [ $locally -eq 0 ] && [ $clear_overlayfs -eq 0 ] ); then print_usage echo one exit 1 fi if [ $remotely -eq 0 ] && [ $locally -eq 0 ] && [ $clear_overlayfs -eq 1 ]; then clearing_overlayfs && quick_reboot exit 1 fi [ -z "${kernel_file}" ] && kernel_file="/tmp/uImage.${soc}" [ -z "${rootfs_file}" ] && rootfs_file="/tmp/rootfs.squashfs.${soc}" if [ $remotely -eq 1 ]; then if [ $from_url -eq 1 ]; then if [ -z "${url}" ]; then echo -e "\n\e[1;31mThere is no URL to update file...\e[0m\n" exit 1 fi else if [ "$(curl -o /dev/null -s -w '%{http_code}\n' http://github.com)" != "301" ]; then echo -e "\n\e[1;31mThere is no access to the github.com, please check the Internet connection...\e[0m\n" exit 1 fi url="${github}/openipc.${soc}-br.tgz" fi fi stop_services unload_modules download_firmware "${url}" && check_memory && writing_kernel "${kernel_file}" && writing_rootfs "${rootfs_file}" && sleep 1 && clearing_overlayfs && quick_reboot