From c35bad328703cae4268f1df6290cd86ebfa1bbe8 Mon Sep 17 00:00:00 2001 From: aiamadeus <2789289348@qq.com> Date: Wed, 14 Aug 2024 23:09:19 +0800 Subject: [PATCH] ipq40xx: use old upgrade scripts for asus ac42u/ac58u --- .../base-files/lib/upgrade/platform.sh | 162 +++++++++++++++--- target/linux/ipq40xx/image/generic.mk | 4 + 2 files changed, 146 insertions(+), 20 deletions(-) diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh index e9c17e5b0..8ee7cedcf 100644 --- a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh +++ b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh @@ -4,27 +4,142 @@ REQUIRE_IMAGE_METADATA=1 RAMFS_COPY_BIN='fw_printenv fw_setenv' RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock' +ubi_kill_if_exist() { + local ubidev="$( nand_find_ubi "$CI_UBIPART" )" + local c_ubivol="$( nand_find_volume $ubidev $1 )" + umount -f /dev/$c_ubivol 2>/dev/null + [ "$c_ubivol" ] && ubirmvol /dev/$ubidev -N $1 || true + echo "Partition $1 removed." +} + +# idea from @981213 +# Tar sysupgrade for ASUS RT-AC82U/RT-AC58U +# An ubi repartition is required due to the strange partition table created by Asus. +# We create all the factory partitions to make sure that the U-boot tftp recovery still works. +# The reserved kernel partition size should be enough to put the factory image in. +asus_nand_upgrade_tar() { + local kpart_size="$1" + local tar_file="$2" + + local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$') + board_dir=${board_dir%/} + + local kernel_length=`(tar xf $tar_file ${board_dir}/kernel -O | wc -c) 2> /dev/null` + local rootfs_length=`(tar xf $tar_file ${board_dir}/root -O | wc -c) 2> /dev/null` + + local mtdnum="$( find_mtd_index "$CI_UBIPART" )" + if [ ! "$mtdnum" ]; then + echo "cannot find ubi mtd partition $CI_UBIPART" + return 1 + fi + + local ubidev="$( nand_find_ubi "$CI_UBIPART" )" + if [ ! "$ubidev" ]; then + ubiattach -m "$mtdnum" + sync + ubidev="$( nand_find_ubi "$CI_UBIPART" )" + fi + + if [ ! "$ubidev" ]; then + echo "cannot find ubi device $CI_UBIPART" + return 1 + fi + + local root_ubivol="$( nand_find_volume $ubidev rootfs )" + # remove ubiblock device of rootfs + local root_ubiblk="ubiblock${root_ubivol:3}" + if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then + echo "removing $root_ubiblk" + if ! ubiblock -r /dev/$root_ubivol; then + echo "cannot remove $root_ubiblk" + return 1; + fi + fi + + ubi_kill_if_exist rootfs_data + ubi_kill_if_exist rootfs + ubi_kill_if_exist jffs2 + ubi_kill_if_exist linux2 + ubi_kill_if_exist linux + + ubimkvol /dev/$ubidev -N linux -s $kpart_size + ubimkvol /dev/$ubidev -N linux2 -s $kpart_size + ubimkvol /dev/$ubidev -N jffs2 -s 2539520 + ubimkvol /dev/$ubidev -N rootfs -s $rootfs_length + ubimkvol /dev/$ubidev -N rootfs_data -m + + local kern_ubivol="$(nand_find_volume $ubidev $CI_KERNPART)" + echo "Kernel at $kern_ubivol.Writing..." + tar xf $tar_file ${board_dir}/kernel -O | \ + ubiupdatevol /dev/$kern_ubivol -s $kernel_length - + echo "Done." + + local root_ubivol="$(nand_find_volume $ubidev rootfs)" + echo "Rootfs at $root_ubivol.Writing..." + tar xf $tar_file ${board_dir}/root -O | \ + ubiupdatevol /dev/$root_ubivol -s $rootfs_length - + echo "Done." + + nand_do_upgrade_success +} + +# idea from @981213 +# Factory image sysupgrade for ASUS RT-AC82U/RT-AC58U +# Delete all the partitions we created before, create "linux" partition and write factory image in. +# Skip the first 64bytes which is an uImage header to verify the firmware. +# The kernel partition size should be the original one. +asus_nand_upgrade_factory() { + local kpart_size="$1" + local fw_file="$2" + + local mtdnum="$( find_mtd_index "$CI_UBIPART" )" + if [ ! "$mtdnum" ]; then + echo "cannot find ubi mtd partition $CI_UBIPART" + return 1 + fi + + local ubidev="$( nand_find_ubi "$CI_UBIPART" )" + if [ ! "$ubidev" ]; then + ubiattach -m "$mtdnum" + sync + ubidev="$( nand_find_ubi "$CI_UBIPART" )" + fi + + if [ ! "$ubidev" ]; then + echo "cannot find ubi device $CI_UBIPART" + return 1 + fi + + local root_ubivol="$( nand_find_volume $ubidev rootfs )" + # remove ubiblock device of rootfs + local root_ubiblk="ubiblock${root_ubivol:3}" + if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then + echo "removing $root_ubiblk" + if ! ubiblock -r /dev/$root_ubivol; then + echo "cannot remove $root_ubiblk" + return 1; + fi + fi + + ubi_kill_if_exist rootfs_data + ubi_kill_if_exist rootfs + ubi_kill_if_exist jffs2 + ubi_kill_if_exist linux2 + ubi_kill_if_exist linux + + ubimkvol /dev/$ubidev -N linux -s $kpart_size + + local kern_ubivol="$(nand_find_volume $ubidev $CI_KERNPART)" + echo "Asus linux at $kern_ubivol.Writing..." + ubiupdatevol /dev/$kern_ubivol --skip=64 $fw_file + echo "Done." + + umount -a + reboot -f +} + platform_check_image() { case "$(board_name)" in - asus,rt-ac42u |\ - asus,rt-ac58u) - local ubidev=$(nand_find_ubi $CI_UBIPART) - local asus_root=$(nand_find_volume $ubidev jffs2) - - [ -n "$asus_root" ] || return 0 - - cat << EOF -jffs2 partition is still present. -There's probably no space left -to install the filesystem. - -You need to delete the jffs2 partition first: -# ubirmvol /dev/ubi0 --name=jffs2 - -Once this is done. Retry. -EOF - return 1 - ;; zte,mf286d |\ zte,mf289f) CI_UBIPART="rootfs" @@ -143,8 +258,15 @@ platform_do_upgrade() { ;; asus,rt-ac42u |\ asus,rt-ac58u) + local magic=$(get_magic_long "$1") + CI_UBIPART="UBI_DEV" CI_KERNPART="linux" - nand_do_upgrade "$1" + if [ "$magic" == "27051956" ]; then + echo "Got Asus factory image." + asus_nand_upgrade_factory 50409472 "$1" + else + asus_nand_upgrade_tar 20951040 "$1" + fi ;; cellc,rtl30vw) CI_UBIPART="ubifs" diff --git a/target/linux/ipq40xx/image/generic.mk b/target/linux/ipq40xx/image/generic.mk index 1b6630242..b3f596a9c 100644 --- a/target/linux/ipq40xx/image/generic.mk +++ b/target/linux/ipq40xx/image/generic.mk @@ -223,6 +223,8 @@ define Device/asus_rt-ac42u # Rather, this device is a/k/a RT-AC42U # But we'll go with what the vendor firmware has... UIMAGE_NAME:=$(shell echo -e '\03\01\01\01RT-AC82U') + KERNEL_INITRAMFS := $$(KERNEL) | uImage none + KERNEL_INITRAMFS_SUFFIX := -factory.trx DEVICE_PACKAGES := ath10k-firmware-qca9984-ct kmod-usb-ledtrig-usbport endef TARGET_DEVICES += asus_rt-ac42u @@ -244,6 +246,8 @@ define Device/asus_rt-ac58u # to add a version... or we are very careful not to add '\0' into that # string and call it a day.... Yeah, we do the latter! UIMAGE_NAME:=$(shell echo -e '\03\01\01\01RT-AC58U') + KERNEL_INITRAMFS := $$(KERNEL) | uImage none + KERNEL_INITRAMFS_SUFFIX := -factory.trx DEVICE_PACKAGES := -kmod-ath10k-ct kmod-ath10k-ct-smallbuffers \ kmod-usb-ledtrig-usbport endef