mirror of https://github.com/OpenIPC/firmware.git
				
				
				
			rewrite to minimize code footprint and redundancy.
							parent
							
								
									ac42c54ad6
								
							
						
					
					
						commit
						edf4f9de0c
					
				|  | @ -1,268 +1,228 @@ | |||
| #!/bin/sh | ||||
| # | ||||
| # OpenIPC.org | v.20220221 | ||||
| # OpenIPC.org | v.20220222 | ||||
| # | ||||
| 
 | ||||
| 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 | ||||
| echo_c() { | ||||
| 	[ -z "$HASERLVER" ] && t="\e[1;$1m$2\e[0m" || t="$2" | ||||
| 	echo -e "$t" | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| die() { | ||||
| 	echo_c 31 "$1 Aborting." | ||||
| 	reboot_system | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| 	[ "$skip_soc" -eq 1 ] && echo "Skip SoC validation" && return 0 | ||||
| 	[ "$1" = "$soc" ] && echo "SoC OK" && return 0 | ||||
| 	die "Wrong SoC!" | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| compare_versions() { | ||||
| 	[ "$skip_ver" -eq 1 ] && echo "Skip version checking" && return 1 | ||||
| 	[ "$1" = "$2" ] && echo_c 32 "Same version, nothing to update" && return 0 | ||||
| 	echo_c 32 "New version, going to update" && return 1 | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| do_update_kernel() { | ||||
| 	x=$1 | ||||
| 	[ -z "$x" ] && x="/tmp/uImage.$soc" | ||||
| 	echo_c 33 "\nKernel" | ||||
| 	echo "Update kernel from $x" | ||||
| 	[ ! -f "$x" ] && die "File $x not found" | ||||
| 	check_soc "$(od -j 32 -N 32 -S 1 -A n "$x" | cut -d- -f3)" | ||||
| 	compare_versions "$kernel_version" "$(get_kernel_version "$x")" && return 0 | ||||
| 	flashcp -v "$x" "$kernel_device" | ||||
| 	echo_c 32 "Kernel updated to $(get_kernel_version "$kernel_device")" | ||||
| 	unset x | ||||
| } | ||||
| 
 | ||||
| writing_kernel() { | ||||
|   if [ $update_kernel -eq 1 ]; then | ||||
|     check_sum "${1}" "Kernel" | ||||
| do_update_rootfs() { | ||||
| 	x=$1 | ||||
| 	[ -z "$x" ] && x="/tmp/rootfs.squashfs.$soc" | ||||
| 	echo_c 33 "\nRootFS" | ||||
| 	echo "Update rootfs from $x" | ||||
| 	[ ! -f "$x" ] && die "File ${x} not found" | ||||
| 	y=/tmp/rootfs | ||||
| 	if mkdir -p "$y" && loop=$(losetup -f) && losetup "$loop" "$x" && mount "$loop" "$y"; then | ||||
| 		check_soc "$(head -1 ${y}/etc/hostname | cut -d- -f2)" | ||||
| 		compare_versions "$system_version" "$(get_system_version "$y")" && return 0 | ||||
| 		umount "$y" && rm -rf "$y" && losetup -d "$loop" | ||||
| 	else | ||||
| 		die "Unable to mount $y!" | ||||
| 	fi | ||||
| 	unset y | ||||
| 
 | ||||
|     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 | ||||
| 	flashcp -v "$x" "$(get_device "rootfs")" | ||||
| 	echo_c 32 "RootFS updated to $(get_system_version "")" | ||||
| 	unset x | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| do_wipe_overlay() { | ||||
| 	echo_c 33 "\nOverlayFS" | ||||
| 	echo "Erase overlay partition" | ||||
| 	flash_eraseall -j "$(get_device "rootfs_data")" | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| download_firmware() { | ||||
| 	echo_c 33 "\nFirmware" | ||||
| 	[ -z "$url" ] && url="https://github.com/OpenIPC/firmware/releases/download/latest/openipc.${soc}-br.tgz" | ||||
| 	echo "Download from $url" | ||||
| 	[ -z "$HASERLVER" ] && progress="-#" || progress="-s" | ||||
| 	[ "$(curl -o /dev/null -s -w '%{http_code}\n' "$url")" = "000" ] && die "Check your network!" | ||||
| 	curl --connect-timeout 30 -m 60 -L "$url" ${progress} -o - | gzip -d | tar xf - -C /tmp || die "Cannot retrieve $url" | ||||
| 	if [ "$skip_md5" -eq 0 ]; then | ||||
| 		(cd /tmp && md5sum -s -c *.md5sum) || die "Wrong checksum!" | ||||
| 	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 | ||||
| free_resources() { | ||||
| 	echo_c 97 "\nStop services, unload modules" | ||||
| 	killall majestic crond klogd ntpd rngd syslogd >/dev/null 2>&1 || true | ||||
| 	"load_$vendor" -r >/dev/null 2>&1 || true | ||||
| } | ||||
| 
 | ||||
| get_device() { | ||||
| 	echo -n "/dev/$(grep "\"$1\"" /proc/mtd | cut -d: -f1)" | ||||
| } | ||||
| 
 | ||||
| get_kernel_version() { | ||||
| 	echo -n "0x$(xxd -l 4 -s 8 -p "$1" | xargs)" | ||||
| } | ||||
| 
 | ||||
| get_system_info() { | ||||
| 	vendor=$(ipcinfo --vendor) | ||||
| 	soc=$(fw_printenv -n soc) || die "SoC is not defined in U-Boot environment" | ||||
| 	kernel_device=$(get_device "kernel") | ||||
| 	kernel_version=$(get_kernel_version "$kernel_device") | ||||
| 	system_version=$(get_system_version "") | ||||
| } | ||||
| 
 | ||||
| get_system_version() { | ||||
| 	grep "GITHUB_VERSION" "$1/etc/os-release" | head -1 | cut -d= -f2 | sed 's/"//g' | ||||
| } | ||||
| 
 | ||||
| print_sysinfo() { | ||||
| 	get_system_info | ||||
| 	echo_c 33 "OpenIPC System Updater" | ||||
| 	echo_c 96 "\nVendor\t$vendor\nSoC\t$soc\nKernel\t$kernel_version\nRootFS\t$system_version" | ||||
| } | ||||
| 
 | ||||
| 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" | ||||
| 	echo " | ||||
| Usage: $0 [options] | ||||
| 
 | ||||
|   -k			update kernel from online repository | ||||
|   -r			update rootfs from online repository | ||||
|       --url=[URL]	custom URL to update from (.tgz format) | ||||
|       --kernel=[FILE]	update kernel from file (uImage format) | ||||
|       --rootfs=[FILE]	update rootfs from file (squashfs format) | ||||
|       --force_md5	do not validate MD5 hash | ||||
|       --force_soc	do not validate processor | ||||
|       --force_ver	do not validate release version | ||||
|       --force_all	do not validate anything | ||||
|   -n, --wipe_overlay	wipe overlay partition | ||||
|   -x, --no_reboot	do not reboot after updating | ||||
|   -h, --help		display this help and exit | ||||
| " | ||||
| } | ||||
| 
 | ||||
| reboot_system() { | ||||
| 	[ "$skip_reboot" -eq 1 ] && echo_c 31 "\nReboot needed!" && exit 1 | ||||
| 	echo_c 97 "\nUnconditional reboot" | ||||
| 	reboot -d 1 -f | ||||
| } | ||||
| 
 | ||||
| clear_overlay=0 | ||||
| remote_update=0 | ||||
| skip_md5=0 | ||||
| skip_soc=0 | ||||
| skip_ver=0 | ||||
| skip_reboot=0 | ||||
| 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     | ||||
| for i in "$@"; do | ||||
| 	case $i in | ||||
| 	--force_all) | ||||
| 		skip_md5=1 | ||||
| 		skip_soc=1 | ||||
| 		skip_ver=1 | ||||
| 		shift | ||||
| 		;; | ||||
| 	--force_md5) | ||||
| 		skip_md5=1 | ||||
| 		shift | ||||
| 		;; | ||||
| 	--force_soc) | ||||
| 		skip_soc=1 | ||||
| 		shift | ||||
| 		;; | ||||
| 	--force_ver) | ||||
| 		skip_ver=1 | ||||
| 		shift | ||||
| 		;; | ||||
| 	-h|--help) | ||||
| 		print_sysinfo | ||||
| 		print_usage | ||||
| 		exit 0 | ||||
| 		;; | ||||
| 	-k ) | ||||
| 		update_kernel=1 | ||||
| 		remote_update=1 | ||||
| 		shift | ||||
| 		;; | ||||
| 	--kernel=*) | ||||
| 		update_kernel=1 | ||||
| 		kernel_file="${i#*=}" | ||||
| 		shift | ||||
| 		;; | ||||
| 	-n|--wipe_overlay) | ||||
| 		clear_overlay=1 | ||||
| 		shift | ||||
| 		;; | ||||
| 	-r) | ||||
| 		update_rootfs=1 | ||||
| 		remote_update=1 | ||||
| 		shift | ||||
| 		;; | ||||
| 	--rootfs=*) | ||||
| 		update_rootfs=1 | ||||
| 		rootfs_file="${i#*=}" | ||||
| 		shift | ||||
| 		;; | ||||
| 	--url=*) | ||||
| 		url="${i#*=}" | ||||
| 		shift | ||||
| 		;; | ||||
| 	-x|--no_reboot) | ||||
| 		skip_reboot=1 | ||||
| 		shift | ||||
| 		;; | ||||
| 	*) | ||||
| 		print_sysinfo | ||||
| 		echo_c 97 "\nUnknown option: $1" | ||||
| 		print_usage | ||||
| 		exit 1 | ||||
| 		;; | ||||
| 	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 | ||||
| print_sysinfo | ||||
| 
 | ||||
| if [ $remotely -eq 0 ] && [ $locally -eq 0 ] && [ $clear_overlayfs -eq 1 ]; then | ||||
|   clearing_overlayfs && quick_reboot | ||||
|   exit 1 | ||||
| fi | ||||
| [ "$update_kernel" -eq 0 ] && \ | ||||
| [ "$update_rootfs" -eq 0 ] && \ | ||||
| [ "$clear_overlay" -eq 0 ] && \ | ||||
| echo_c 97 "\nTry '$(basename "$0") --help' for options." && \ | ||||
| exit 0 | ||||
| 
 | ||||
| [ -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 | ||||
| free_resources | ||||
| [ "$remote_update" -eq 1 ] && download_firmware | ||||
| [ "$update_kernel" -eq 1 ] && do_update_kernel "$kernel_file" | ||||
| [ "$update_rootfs" -eq 1 ] && do_update_rootfs "$rootfs_file" | ||||
| [ "$clear_overlay" -eq 1 ] && do_wipe_overlay | ||||
| reboot_system | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue