1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter.git synced 2025-02-13 20:01:55 +00:00
openmptcprouter/5.4/target/linux/ipq40xx/base-files/lib/upgrade/ipq_failsafe.sh

383 lines
9.5 KiB
Bash

find_mmc_part() {
local DEVNAME PARTNAME
if grep -q "$1" /proc/mtd; then
echo "" && return 0
fi
for DEVNAME in /sys/block/mmcblk0/mmcblk*p*; do
PARTNAME=$(grep PARTNAME ${DEVNAME}/uevent | cut -f2 -d'=')
[ "$PARTNAME" = "$1" ] && echo "/dev/$(basename $DEVNAME)" && return 0
done
}
get_full_section_name() {
local img=$1
local sec=$2
dumpimage -l ${img} | grep "^ Image.*(${sec})" | \
sed 's,^ Image.*(\(.*\)),\1,'
}
image_contains() {
local img=$1
local sec=$2
dumpimage -l ${img} | grep -q "^ Image.*(${sec}.*)" || return 1
}
print_sections() {
local img=$1
dumpimage -l ${img} | awk '/^ Image.*(.*)/ { print gensub(/Image .* \((.*)\)/,"\\1", $0) }'
}
image_has_mandatory_section() {
local img=$1
local mandatory_sections=$2
for sec in ${mandatory_sections}; do
image_contains $img ${sec} || {\
return 1
}
done
}
image_demux() {
local img=$1
for sec in $(print_sections ${img}); do
local fullname=$(get_full_section_name ${img} ${sec})
local position=$(dumpimage -l ${img} | grep "(${fullname})" | awk '{print $2}')
dumpimage -i ${img} -o /tmp/${fullname}.bin -T "flat_dt" -p "${position}" ${fullname} > /dev/null || { \
echo "Error while extracting \"${sec}\" from ${img}"
return 1
}
done
return 0
}
image_is_FIT() {
if ! dumpimage -l $1 > /dev/null 2>&1; then
echo "$1 is not a valid FIT image"
return 1
fi
return 0
}
switch_layout() {
local layout=$1
local boot_layout=`find / -name boot_layout`
# Layout switching is only required as the boot images (up to u-boot)
# use 512 user data bytes per code word, whereas Linux uses 516 bytes.
# It's only applicable for NAND flash. So let's return if we don't have
# one.
[ -n "$boot_layout" ] || return
case "${layout}" in
boot|1) echo 1 > $boot_layout;;
linux|0) echo 0 > $boot_layout;;
*) echo "Unknown layout \"${layout}\"";;
esac
}
do_flash_mtd() {
local bin=$1
local mtdname=$2
local append=""
local mtdpart=$(grep "\"${mtdname}\"" /proc/mtd | awk -F: '{print $1}')
local pgsz=$(cat /sys/class/mtd/${mtdpart}/writesize)
[ -f "$CONF_TAR" -a "$SAVE_CONFIG" -eq 1 -a "$2" == "rootfs" ] && append="-j $CONF_TAR"
dd if=/tmp/${bin}.bin bs=${pgsz} conv=sync | mtd $append -e "/dev/${mtdpart}" write - "/dev/${mtdpart}"
}
do_flash_emmc() {
local bin=$1
local emmcblock=$2
dd if=/dev/zero of=${emmcblock}
dd if=/tmp/${bin}.bin of=${emmcblock}
}
do_flash_partition() {
local bin=$1
local mtdname=$2
local emmcblock="$(find_mmc_part "$mtdname")"
if [ -e "$emmcblock" ]; then
do_flash_emmc $bin $emmcblock
else
do_flash_mtd $bin $mtdname
fi
}
do_flash_bootconfig() {
local bin=$1
local mtdname=$2
# Fail safe upgrade
if [ -f /proc/boot_info/getbinary_${bin} ]; then
cat /proc/boot_info/getbinary_${bin} > /tmp/${bin}.bin
do_flash_partition $bin $mtdname
fi
}
do_flash_failsafe_partition() {
local bin=$1
local mtdname=$2
local emmcblock
local primaryboot
# Fail safe upgrade
[ -f /proc/boot_info/$mtdname/upgradepartition ] && {
default_mtd=$mtdname
mtdname=$(cat /proc/boot_info/$mtdname/upgradepartition)
primaryboot=$(cat /proc/boot_info/$default_mtd/primaryboot)
if [ $primaryboot -eq 0 ]; then
echo 1 > /proc/boot_info/$default_mtd/primaryboot
else
echo 0 > /proc/boot_info/$default_mtd/primaryboot
fi
}
emmcblock="$(find_mmc_part "$mtdname")"
if [ -e "$emmcblock" ]; then
do_flash_emmc $bin $emmcblock
else
do_flash_mtd $bin $mtdname
fi
}
do_flash_ubi() {
local bin=$1
local mtdname=$2
local mtdpart
local primaryboot
mtdpart=$(grep "\"${mtdname}\"" /proc/mtd | awk -F: '{print $1}')
ubidetach -p /dev/${mtdpart}
# Fail safe upgrade
[ -f /proc/boot_info/$mtdname/upgradepartition ] && {
primaryboot=$(cat /proc/boot_info/$mtdname/primaryboot)
if [ $primaryboot -eq 0 ]; then
echo 1 > /proc/boot_info/$mtdname/primaryboot
else
echo 0 > /proc/boot_info/$mtdname/primaryboot
fi
mtdname=$(cat /proc/boot_info/$mtdname/upgradepartition)
}
mtdpart=$(grep "\"${mtdname}\"" /proc/mtd | awk -F: '{print $1}')
ubiformat /dev/${mtdpart} -y -f /tmp/${bin}.bin
}
do_flash_tz() {
local sec=$1
local mtdpart=$(grep "\"0:QSEE\"" /proc/mtd | awk -F: '{print $1}')
local emmcblock="$(find_mmc_part "0:QSEE")"
if [ -n "$mtdpart" -o -e "$emmcblock" ]; then
do_flash_failsafe_partition ${sec} "0:QSEE"
else
do_flash_failsafe_partition ${sec} "0:TZ"
fi
}
do_flash_ddr() {
local sec=$1
local mtdpart=$(grep "\"0:CDT\"" /proc/mtd | awk -F: '{print $1}')
local emmcblock="$(find_mmc_part "0:CDT")"
if [ -n "$mtdpart" -o -e "$emmcblock" ]; then
do_flash_failsafe_partition ${sec} "0:CDT"
else
do_flash_failsafe_partition ${sec} "0:DDRPARAMS"
fi
}
to_upper () {
echo $1 | awk '{print toupper($0)}'
}
flash_section() {
local sec=$1
local board=$(board_name)
case "${sec}" in
hlos*) switch_layout linux; do_flash_failsafe_partition ${sec} "0:HLOS";;
rootfs*) switch_layout linux; do_flash_failsafe_partition ${sec} "rootfs";;
fs*) switch_layout linux; do_flash_failsafe_partition ${sec} "rootfs";;
ubi*) switch_layout linux; do_flash_ubi ${sec} "rootfs";;
#sbl1*) switch_layout boot; do_flash_partition ${sec} "0:SBL1";;
#sbl2*) switch_layout boot; do_flash_failsafe_partition ${sec} "0:SBL2";;
#sbl3*) switch_layout boot; do_flash_failsafe_partition ${sec} "0:SBL3";;
#mibib*) switch_layout boot; do_flash_partition ${sec} "0:MIBIB";;
#dtb-$(to_upper $board)*) switch_layout boot; do_flash_partition ${sec} "0:DTB";;
u-boot*) switch_layout boot; do_flash_failsafe_partition ${sec} "0:APPSBL";;
#ddr-$(to_upper $board)*) switch_layout boot; do_flash_ddr ${sec};;
ddr-${board}-*) switch_layout boot; do_flash_failsafe_partition ${sec} "0:CDT";;
#ssd*) switch_layout boot; do_flash_partition ${sec} "0:SSD";;
tz*) switch_layout boot; do_flash_tz ${sec};;
#rpm*) switch_layout boot; do_flash_failsafe_partition ${sec} "0:RPM";;
*) echo "Section ${sec} ignored"; return 1;;
esac
echo "Flashed ${sec}"
}
erase_emmc_config() {
local emmcblock="$(find_mmc_part "rootfs_data")"
if [ -e "$emmcblock" ]; then
dd if=/dev/zero of=${emmcblock}
mkfs.ext4 "$emmcblock"
fi
}
platform_pre_upgrade() {
cp /sbin/upgraded /tmp
ubus call system nandupgrade "{\"path\": \"$1\" }"
}
platform_check_image_ipq() {
local board=$(board_name)
local mandatory_nand="ubi"
local mandatory_nor_emmc="hlos fs"
local mandatory_nor="hlos"
local mandatory_section_found=0
local optional="sbl2 u-boot ddr-${board} ssd tz rpm"
local ignored="mibib bootconfig sbl1"
image_is_FIT $1 || return 1
image_has_mandatory_section $1 ${mandatory_nand} && {\
mandatory_section_found=1
}
image_has_mandatory_section $1 ${mandatory_nor_emmc} && {\
mandatory_section_found=1
}
image_has_mandatory_section $1 ${mandatory_nor} && {\
mandatory_section_found=1
}
if [ $mandatory_section_found -eq 0 ]; then
echo "Error: mandatory section(s) missing from \"$1\". Abort..."
return 1
fi
for sec in ${optional}; do
image_contains $1 ${sec} || {\
echo "Warning: optional section \"${sec}\" missing from \"$1\". Continue..."
}
done
for sec in ${ignored}; do
image_contains $1 ${sec} && {\
echo "Warning: section \"${sec}\" will be ignored from \"$1\". Continue..."
}
done
image_demux $1 || {\
echo "Error: \"$1\" couldn't be extracted. Abort..."
return 1
}
[ -f /tmp/hlos_version ] && rm -f /tmp/*_version
dumpimage -c $1 2>/dev/null
return $?
}
platform_version_upgrade() {
local version_files="appsbl_version sbl_version tz_version hlos_version rpm_version"
local sys="/sys/devices/system/qfprom/qfprom0/"
local tmp="/tmp/"
for file in $version_files; do
[ -f "${tmp}${file}" ] && {
echo "Updating "${sys}${file}" with `cat "${tmp}${file}"`"
echo `cat "${tmp}${file}"` > "${sys}${file}"
rm -f "${tmp}${file}"
}
done
}
# The U-Boot loader of the OpenMesh devices requires image sizes and
# checksums to be provided in the U-Boot environment.
# The OpenMesh devices come with 2 main partitions - while one is active
# sysupgrade will flash the other. The boot order is changed to boot the
# newly flashed partition. If the new partition can't be booted due to
# upgrade failures the previously used partition is loaded.
platform_do_upgrade_ipq() {
local board=$(board_name)
# verify some things exist before erasing
if [ ! -e $1 ]; then
echo "Error: Can't find $1 after switching to ramfs, aborting upgrade!"
reboot
fi
for sec in $(print_sections $1); do
if [ ! -e /tmp/${sec}.bin ]; then
echo "Error: Cant' find ${sec} after switching to ramfs, aborting upgrade!"
reboot
fi
done
case "$board" in
teltonika,rutx)
for sec in $(print_sections $1); do
flash_section ${sec}
done
switch_layout linux
# update bootconfig to register that fw upgrade has been done
do_flash_bootconfig bootconfig "0:BOOTCONFIG"
do_flash_bootconfig bootconfig1 "0:BOOTCONFIG1"
platform_version_upgrade
erase_emmc_config
return 0;
;;
esac
echo "Upgrade failed!"
return 1;
}
platform_copy_config_ipq() {
local emmcblock="$(find_mmc_part "rootfs_data")"
mkdir -p /tmp/overlay
if [ -e "$emmcblock" ]; then
mount -t ext4 "$emmcblock" /tmp/overlay
cp /tmp/sysupgrade.tgz /tmp/overlay/
sync
umount /tmp/overlay
else
local mtdname=rootfs
local mtdpart
[ -f /proc/boot_info/$mtdname/upgradepartition ] && {
mtdname=$(cat /proc/boot_info/$mtdname/upgradepartition)
}
mtdpart=$(grep "\"${mtdname}\"" /proc/mtd | awk -F: '{print $1}')
ubiattach -p /dev/${mtdpart}
mount -t ubifs ubi0:rootfs_data /tmp/overlay
cp /tmp/sysupgrade.tgz /tmp/overlay/
sync
umount /tmp/overlay
fi
}