Resize MTD partitions at runtime

2020-07-13 09:39发布

问题:

I am working with embedded devices and would like to enable them to resize their MTD partitions via Linux without rebooting.

The problem is that my Linux image size has increased and the current MTD partition (mtd0) in which it resides is now too small. However, the partition right after it (mtd1) is a JFFS2 section used for storing config information, so resizing with a reboot is not an option because the config could be lost.

My goal is this:

1. Copy contents of JFFS2 into /tmp/
2. Unmount JFFS2 from mtd1
3. Increase the starting offset + reduce size of mtd1 by X bytes (or delete mtd1 and create new mtd of proper size and offset)
4. Mount JFFS2 on new mtd1 and restore contents from /tmp/
5. Increase the size of mtd0 by X bytes
6. Burn new (larger) Linux image into mtd0 (the new image will contain a device tree with an updated partition structure)
7. Reboot

I found a proposed patch to "mtd-utils" from a couple years back:

http://article.gmane.org/gmane.linux.drivers.mtd/30949
http://article.gmane.org/gmane.linux.drivers.mtd/30950
http://article.gmane.org/gmane.linux.drivers.mtd/30951

Using this as a guide I was able to write kernel and user-space code to create a new MTD partition on which I can mount JFFS2. However, this code does not properly delete partitions. Even after unmounting JFFS2 from mtd1 and calling put_mtd_device, when del_mtd_device is called the kernel complains:

user.notice kernel: Removing MTD device #1 (jffs2) with use count 1 

What I'd like to know is:

1. How to fix the patch to allow deleting my old mtd1
2. How to change the starting offset of mtd1 instead of creating/deleting partitions

I tried contacting the author of the patch, but their email is no longer valid, so I would appreciate any suggestions!


UPDATE:

It seems that mtd_open() in mtdchar.c triggers a get_mtd_device(), which probably accounts for the extra usecount increment. But my userspace app needs to call open() on the partition to send it an ioctl() for deleting a partition :/ catch 22? Is there a more correct way of doing this?

回答1:

I ended up solving this issue by having my patched mtd utility increase "mtd0" size, then create a brand new partition of the correct reduced size to mount JFFS on, which gave me a chance to copy the config info into the new flash location.

To reduce complexity, I also made it so I couldn't run this app more than once. It ended up being a "run once, do your thing, reboot" type of procedure.


UPDATE:

Here's my code, figured it could benefit some folks:

https://github.com/mikzat/mtd_runtime_partition