EA7300, Flash to "Wrong" Partition

Hi,

The EA7300 is a dual partition / firmware device, and when flashing it should always be done to the "other" (inactive) partition. But for this device, the flash is to the active partition, not to the backup. Is there a way to manually force / control this? Or perhaps in the sysupgrade scripts somehow?

Thanks!

the file of interest is

target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh

it seems to share the same upgrade function nand_do_upgrade
with many other boards that are not dual-boot

probably the "feature" where it upgrades the partition not currently being used is only possible with NOR flash somehow, so the device having NAND flash is limiting this, but I don't know for sure

the original commit message describes going back to the "B" partition in order to revert to factory firmware.

Will do some digging - my other dual partition router (EA3500) does do this "correctly"

Thanks!

FYI, just to let you know - it seems both devices are using NAND flash, only delta seems to be which partition is being written to. Hmmm.

Thanks!

EA3500 is in the "kirkwood" target (Marvel SOC) where
EA7300 is a Mediatek SOC

so despite the model names there is many differences

EA3500 for upgrade uses a different function
platform_do_upgrade_linksys
in another file
target/linux/kirkwood/base-files/lib/upgrade/platform.sh

and this function is defined here
target/linux/kirkwood/base-files/lib/upgrade/linksys.sh

and the function grabs values from fw_printenv

theres also probably some differences in partitioning and partition types, like you said
SQUASHFS vs UBI
you can see if this is the case by comparing the DTS files (and makefiles)

if they are similar enough you're welcome to try adding a function to the mediatek platform.sh
target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh

1 Like

Yep, exactly where I'm at :laughing:. We're on the same page, agreed!

And BTW, checked magic (partition header) on both routers (3500, 7300) - they are the same.

OK, now this is very odd! Or may just be me :rofl:. I see that the only / main issue is just writing to the wrong partition - seems simple enough. But I'm not really following the script flow ... yet). I looked at /sbin/sysupgrade, and made a slight mod near the end,

echo "$(json_dump)"
#       ubus call system sysupgrade "$(json_dump)"

As expected, the output shows,

Tue Jan 12 22:36:50 UTC 2021 upgrade: Saving config files...
Tue Jan 12 22:36:50 UTC 2021 upgrade: Commencing upgrade. Closing all shell sessions.
{ "prefix": "\/tmp\/root", "path": "\/tmp\/openwrt-ramips-mt7621-linksys_ea7300-v2-squashfs-sysupgrade.bin", "backup": "\/tmp\/sysupgrade.tgz", "command": "\/lib\/upgrade\/do_stage2", "options": { "save_partitions": 1 } }

All makes sense so far :grinning_face_with_smiling_eyes:. So then I re-enabled the ubus call => based on the command noted above, I went in to that file (/lib/upgrade/do_stage2), made this mod - just to track through the code,

#!/bin/sh
echo "do_stage2 ..."
exit

And the mystery starts! This never seems to hit, so it never actually runs do_stage2. I may just be losing it (entirely possible!), but seems this is where the upgrade should go ... no? Or does ubus sysupgrade not really call that command, and rather does "it's own thing"? Will keep digging, but any pointers would be greatly appreciated. I'm not quite sure (yet) about the difference between /sbin/sysupgrade and ubus sysupgrade.

Thanks!

2 possibilities I can think of

  • part of sysupgrade is that the JFFS2 /overlay gets unmounted, so all file changes have no effect, you would have to make these changes in the build system so its part of the read-only rootfs
  • depending on the upgrade command, do_stage2 might actually not be used

I think you're right, and that's what is fooling me - items are unmounted, and I'm losing my ssh connection (don't have serial right now), so I can't really see the output from the processing steps. As you say, I need to change items in the build directly.

FYI, I did find this, https://git.openwrt.org/?p=project/procd.git;a=tree;hb=HEAD. Part of my confusion was the sysupgrade script (in /sbin), vs. the sysupgrade ubus command (at the noted link). They are different :laughing:.

Thanks!

Found it! It was a few things,

  1. Do need to call the "linksys" nand update - as it changes the target partition (current vs. alternative). But ...
  2. Found also that the u-boot environment partition was set to r/o, in the dtsi file => can't switch the target partition (as it relies on the environment variable setting, boot_part). Then,
  3. The second firmware partition was also r/o, so even once the boot_part was set correctly, it wasn't possible to flash the second firmware.

Applied the changes above ... and it works! So does Advanced Reboot :smiley:.

Submit a new PR I assume, agreed?

Thanks!

1 Like

sounds good

Haven't submitted the PR yet ... only because though the flashing seems to now be working, I can't seem to boot to the second partition. A bit more detail here,

But ... even though I see this on the console (flashing),

Mon Jan 18 21:12:27 UTC 2021 upgrade: Performing system upgrade...
Unlocking alt_kernel ...

Writing from <stdin> to alt_kernel ...
[  134.477737] ubi1: attaching mtd8
[  134.850511] ubi1: scanning is finished
[  134.870612] ubi1: attached mtd8 (name "alt_rootfs", size 36 MiB)
[  134.876650] ubi1: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
[  134.883519] ubi1: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
[  134.890773] ubi1: VID header offset: 2048 (aligned 2048), data offset: 4096
[  134.897738] ubi1: good PEBs: 288, bad PEBs: 0, corrupted PEBs: 0
[  134.903735] ubi1: user volume: 2, internal volumes: 1, max. volumes count: 128
[  134.910962] ubi1: max/mean erase counter: 2/0, WL threshold: 4096, image sequence number: 1940163490
[  134.920077] ubi1: available PEBs: 0, total reserved PEBs: 288, PEBs reserved for bad PEB handling: 20
[  134.929316] ubi1: background thread "ubi_bgt1d" started, PID 4173
UBI device number 1, total 288 LEBs (36569088 bytes, 34.8 MiB), available 0 LEBs (0 bytes), LEB size 126976 bytes (124.0 KiB)
Volume ID 0, size 37 LEBs (4698112 bytes, 4.4 MiB), LEB size 126976 bytes (124.0 KiB), dynamic, name "rootfs", alignment 1
Set volume size to 28823552
Volume ID 1, size 227 LEBs (28823552 bytes, 27.4 MiB), LEB size 126976 bytes (124.0 KiB), dynamic, name "rootfs_data", alignment 1
[  137.418776] UBIFS (ubi1:1): default file-system created
[  137.425386] UBIFS (ubi1:1): Mounting in unauthenticated mode
[  137.431263] UBIFS (ubi1:1): background thread "ubifs_bgt1_1" started, PID 4245
[  137.555715] UBIFS (ubi1:1): UBIFS: mounted UBI device 1, volume 1, name "rootfs_data"
[  137.563584] UBIFS (ubi1:1): LEB size: 126976 bytes (124 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
[  137.573487] UBIFS (ubi1:1): FS size: 27553792 bytes (26 MiB, 217 LEBs), journal size 1396736 bytes (1 MiB, 11 LEBs)
[  137.583892] UBIFS (ubi1:1): reserved for root: 1301433 bytes (1270 KiB)
[  137.590498] UBIFS (ubi1:1): media format: w5/r0 (latest is w5/r0), UUID AD75D6E9-0717-4090-BA38-DDBBF7F9802C, small LPT model
[  137.627065] UBIFS (ubi1:1): un-mount UBI device 1
[  137.631832] UBIFS (ubi1:1): background thread "ubifs_bgt1_1" stops
sysupgrade successful

No matter what I do (fw_setenv, or in U-Boot), I can't seem to boot the second partition. Rather, I always see (ubi0),

root@OpenWrt:/# dmesg | grep mtd
[    2.150167] UBI: auto-attach mtd6
[    2.159337] ubi0: attaching mtd6
[    2.548319] ubi0: attached mtd6 (name "ubi", size 36 MiB)

Thoughts?

Thanks!

have you compared to the DTS of EA3500?

The ARMv7 based ipq40xx/ ipq806x and mvebu routers use the append-rootblock functionality implemented in the custom (so far ARM-only) *-Mangle-bootloader-s-kernel-arguments.patch patch.

2 Likes

Let me dig, this may be part of it! So far, trying to boot from either partition, from U-Boot :grinning_face_with_smiling_eyes:

Thanks!

I know that this is not the topic of this thread however I think that a dual boot router should reserve one partition for OpenWrt and one partition for the OEM FW.
I think that this is a better approach because of the possibility switch easily between OEM fw and OpenWrt if the user wants to.
Moreover I think that this is safer because the OEM firmware is marked as read-only, so it would be nearly impossible to accidentally overwrite the firmware partition or even brick the router.

In the end I would not push an update to unlock the "dual-boot-openwrt-only" feature. Obviously this is just my opinion. :slightly_smiling_face:

Yep, I understand where you are coming from - had similar thoughts. The issue I see is two-fold (if not unlocking those partitions),

  1. this device acts differently (i.e. inconsistent) than the other dual firmware routers out there (and switches as well). "Normal" process is to flash the inactive (backup) partition, which is what this would enable. Of course, you don't have to overwrite the OEM partition, just boot there, and flash (to update OpenWrt, manually restoring settings).
  2. Once you put OpenWrt on the 2nd partition ... you can no longer upgrade the OEM in any case - it's basically stuck on that version, can't be changed (I think :laughing:).

Thoughts?

Not really seeing the append-rootblock functionality for the mt7621 (EA7300v2) ... or am I missing it? But I think you're on to something, even though I set the target root (fs) on the U-boot command line (bootargs), it's not getting to the kernel (i.e. checking dmesg, Kernel command line). But also wondering ... it really seems like my u_env partition got wiped by a flash (early on in developement), thinking that may be it. Hmmm ... seems I should have backed that up :rofl:

As mentioned, the append-rootblock functionality is implemented in a non-mainline, OpenWrt specific patch (*-Mangle-bootloader-s-kernel-arguments.patch applied for mvebu, ipq40xx and ipq806x) - as-is, this patch is ARM specific, so something equivalent will have to be developed for mips as well.

Ahh, OK - think I'm getting your point now :wink:. Do you mean ... the command line is dropping the path (now?), and needs to be added in code? Will need to dig, as I'm not quite sure how to do that (yet) with dual partition.

Thanks!