Mtd resize (to get back to Stock) [Solved]


I was playing around with the dts file on my (EA3500) router ... and it all worked, was able to load a larger (than stock) kernel (up to 3 MB). All good there. But ... when trying to go back to an older build, or stock - they both fail. I'm pretty convinced it's because the kernel size / rootfs split isn't matching now - but I'm struggling to resize the kernel and rootfs partitions / mtd blocks back to the original size. Any leads or suggestions of how to do this?


Hmmm - it may be me, but I updated the dts to re-size (change the kernel vs. rootfs allocation), but even on flashing (sysupgrade) it doesn't seem to change. Or shouldn't it?


It shouldn't.
If you have a normal nand flash sysupgrade routine, it flashes kernel separately and roots separately, to the locations specified by the currently running firmware's DTS.

DTS partitioning is just kernel's internal database about partitions, not a traditional disk partitioning table.

The new modified DTS would get applied by the new kernel at reboot after the flash.

For that reason, you usually need to use the factory image, which is "unified", with padding between kernel and rootfs, so that the rootfs location matches the new location. But depending on the factory file structure (headers etc.) you might need to use other flashing tools than sysupgrade. E.g. with R7800 you needed to use the OEM recovery flash for the factory image.

Ps. That was generic, I have no specific ea3500 knowledge.

The easiest way without serial console is to flash manually a minimal initramfs image (so it has new partition table and sees the partitions like you want) to the kernel partition, boot from that, and then connect and do a sysupgrade to install the firmware on flash with the different partition scheme.

Or since your device has dual partitions you can trigger that and hope the other partition did not have this change

If you have serial console (and if you are playing with firmware development you really should), you can just tftp the factory image to the bootloader and write it.

1 Like

Thanks! Let me do some digging - not thinking I can flash this from sysupgrade, but perhaps I can :laughing:. I need to better understand the different images / formats, but that's on me.

Thanks again.

The (safe) tool to do this in openwrt is mtd

you make an initramfs image from source (better because you can make it very small by not including Luci web interface, opkg and other stuff you don't need) or you download the file called "initramfs-uimage" from the download folder and if it is small enough you can flash it in the kernel partition with mtd (the kernel partition is not used to do much while the device is running, it's not mounted), then you reboot.

If it is too big to fit in the kernel partition you have to use serial console, transfer it over with tftp.
Prepare the show by following this article
then you connect with serial console, stop the booting by pressing a key when you see the uboot text scroll by, then you write

setenv serverip 'IP OF YOUR PC'
setenv ipaddr 'IP OF THE DEVICE'
tftpboot 0x2000000 file-name

then boot it directly from RAM with one of the following commands (at least one should work)

go 0x2000000
bootm 0x2000000
bootz 0x2000000

For example, some devices can be converted to OpenWrt only with this procedure, tftp the initramfs image and then boot it, then connect and do a sysupgrade

1 Like

Yes, that makes sense, thanks! Unfortunately, I don't (easily :stuck_out_tongue_winking_eye:) have serial port access, and the initramfs-uImage file doesn't fit in the kernel partition. But, perhaps another way ...

To the link you sent (MTD), interestingly enough it shows an option,

-F <part>[:<size>[:<entrypoint>]][,<part>…]	alter the fis partition table to create new partitions replacing the partitions provided as argument to the write command (only valid together with the write command)

Seems like this should be the ticket, no? That said, mtd on the router doesn't seem to have the -F option. Huh?!?!

I do also find it interesting ... changing the dts file auto-grows the kernel partition, but then it doesn't auto-shrink if the dts is changed back (for example). Still noodling on that one :grinning_face_with_smiling_eyes:.

Thanks again!

No that option is for editing FIS partition table, which is a thing that exists in devices that use Redboot bootloader.
The bootloader here is u-boot, so that function is disabled.

the dts is part of the kernel image. until you flash a new kernel image, the partition does not change. But it seems you can't flash a kernel image.

Embedded devices are full of these limitations where things are just coded in the kernel and cannot be changed without flashing a new firmware. Doing development without serial access is a pain.

1 Like

Got it - thanks!

Yes, agreed!. Sort of a catch 22 - can't flash a new kernel, because the partitioning doesn't match, and can't re-size (smaller) because I can't flash the new kernel. LOL!

Agreed! I may just have to break into the box :laughing:. Was trying to "avoid" that, but may not be an option.

Again, appreciate the pointers!

OK, close :laughing:. I have 2 routers I'm trying to "fix" ... so added a serial port to one of them. If I just run "nfsboot" (pre-defined in the u-boot environment) => booting that (tftp), and all is good (with the right uImage of course).

But the odd thing - u-boot is not running bootcmd by default, even with bootdelay set (which is the noted prerequisite). Hmmm. If I can just get bootcmd to run (on boot), it's all pretty easy :wink:.



OK, a bit of an update - was able to crawl (two-step :stuck_out_tongue_winking_eye:) my way back, wanted to capture it here for others, hopefully it helps. Thanks @bobafetthotmail for the pointers above! It took a bit to sink in (issue on the receiver end ... LOL!), but once it did, it hit me how to make this work.

A couple key things that play into this - by all means yell if I have any of this wrong!
a) Partition sizes are set when the kernel boots, and the sizes / alignment are taken from the dts values built into the kernel (i.e. from source)
b) sysupgrade doesn't care about or work with sizes, it just "raw" writes to the partitions that exist (and are determined when the kernel boots, from a) above)
c) Dual partition flash is part of how to create (and fix) this issue ... as the non-active sizes can be set "incorrectly" => meaning that the values on the alternative (non-active) side may not match to what is actually flashed there. And it doesn't matter, as these are not in use, for operation at least.

Once I wrapped my head around this, here is how I was able to go back from both current and alternative having 3 MB flash, to the more stock value (2624 kB). Of course, all of this also assumes you can make a custom build, to mess with these settings.

  1. Select a partition to start from (the one that is active). Modify the dts file, to set the desired target / final size of that kernel (the active side), but keep the "other" inactive side sizing to match what is there already (i.e. 3 MB in my case). I know this sounds screwy, but it's because when you flash dual-partition routers, it always flashes to (and then boots), the inactive side. So ... make this build, then flash it. It will come up, with still the larger size in the (now) booted side, but the (now) inactive side will have the desired partitioning. It won't be a functional side right now, as the partitions won't match to what is actually in flash (i.e. they will be misaligned). But,
  2. Make a new build, this time with the dts file modified to get to the final sizes on both partitions (i.e. in my case, both now back to 2624 kB). Build this, flash => now, you will come back to the partition you started this two step on, as the second flash was done based on the misaligned (but desired) partition sizes. So when it boots up ... life is good, back to the desired (smaller) sizing.
  3. Flash one more time, with the same build (image) as in step 2. This is to "solidify" that both (dual) partitions now have correct sizing.

All clear as mud? :laughing:. It really does work (and did!) - just a bit of a two-step (dance) to get there. Of course, yell if you see any issues.

And, as a bit of an added "bonus", this can also be used to get back to OEM stock on one partition if you like. But not 100% straightforward. That's because the OEM file seems to be more of a raw (kernel + rootfs), and needs to be flashed as kernel only. So ... change the dts, to allocate almost the full size of one "side" to kernel, very little to rootfs (but don't remove rootfs, or you won't be able to boot - the total number of partitions can't change, this is key for booting). Then, flash OEM to the large (alternative) side, and reboot. It does come up!

Yell if you have any questions or comments, or if any of this doesn't make sense. I just wanted to try to share this back to folks.

And again, @bobafetthotmail - thanks for the pointers! Also - I do agree with your note ... tftp booting initramfs-uImage is easier, if you have serial port access. Buf if you don't (or don't want to open the router), you can follow the above steps.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.