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