首页 > 解决方案 > 是否可以在运行时调整 MTD 分区的大小?

问题描述

我有一个非常具体的需求:部分替换闪存的内容移动 MTD 分区边界。

目前的地图是:

虽然所需的输出是:

这意味着要崩溃initrdscriptsfilesystem进入一个单独的区域,而让其他区域独自一人。

问题是这应该从正在运行的系统中实现(使用“旧”配置启动)我应该在重新启动之前重写内核和“新”文件系统。

该系统是嵌入式的,所以我没有多少空间进行操作(不过我有一张 SD 卡)。

当然,重写的内核将在其 DTB 中写入“新”配置。

问题是过渡。

注意:我看过这个问题,但它很老,并且需要内核补丁,我想避免它的缺点。

注意2:这个问题已被标记为删除,因为“与编程无关”。我不同意:我需要在大约 14k 设备上执行上述操作,其中大多数已经卖给了客户,所以任何可行的解决方案至少应该包括脚本。

NOTE3:如果绝对必要,我什至可以考虑(小)内核修改(是的,我有办法远程更新内核)。

标签: linuxflash-memorydisk-partitioning

解决方案


我有三个想法/建议:

  1. 您可以将“新”文件系统映像拆分为块并将它们写入相应的“旧”MTD 分区,而不是移动分区吗?这样您就不需要更改 MTD 分区图。启动到新内核后,它将看到新的连续根文件系统。对于 JFFS2 文件系统,使用 split 或 dd、flash_erase 和 nandwrite 应该相当简单。就像是:
# WARNING: this script assumes that it runs from tmpfs and the old root filesystem is already unmounted.
# Also, it assumes that your shell has arithmetic evaluation, which handles hex (my busybox 1.29 ash does this).

# assuming newrootfs.img is the image of new rootfs
new_rootfs_img="newrootfs.img"

mtd_initrd="/dev/mtd3"
mtd_initrd_size=0x170000
mtd_scripts="/dev/mtd4"
mtd_scripts_size=0x010000
mtd_filesystem="/dev/mtd5"
mtd_filesystem_size=0xbf0000

# prepare chunks of new filesystem image
bs="0x1000"
# note: using arithmetic evaluation $(()) to convert from hex and do the math.
# dd doesn't handle hex numbers ("dd: invalid number '0x1000'") -- $(()) works this around
dd if="${new_rootfs_img}" of="rootfs_initrd"     bs=$(( bs )) count=$(( mtd_initrd_size / bs ))
dd if="${new_rootfs_img}" of="rootfs_scripts"    bs=$(( bs )) count=$(( mtd_scripts_size / bs )) skip=$(( mtd_initrd_size / bs ))
dd if="${new_rootfs_img}" of="rootfs_filesystem" bs=$(( bs )) count=$(( mtd_filesystem_size / bs )) skip=$(( ( mtd_initrd_size + mtd_scripts_size ) / bs ))

# there's no going back after this point

flash_eraseall -j "${mtd_initrd}"
flash_eraseall -j "${mtd_scripts}"
flash_eraseall -j "${mtd_filesystem}"

nandwrite -p "${mtd_initrd}"     rootfs_initrd
nandwrite -p "${mtd_scripts}"    rootfs_scripts
nandwrite -p "${mtd_filesystem}" rootfs_filesystem

# don't forget to update the kernel too
  1. 有对连接 MTD 设备的内核支持(这正是您想要做的)。我看不到使用它的简单方法,但您可以创建一个内核模块,它将您所需的分区连接到一个连续的 MTD 设备中。

  2. 为了将 3 个 MTD 分区合并为一个以写入新文件系统,您可以在 3 个 mtdblocks 上创建一个 dm 线性映射,然后使用 block2mtd 将其转回 MTD 设备。(即mtdblock + 设备映射器线性+ block2mtd) 但它看起来很尴尬,我不知道它是否能正常工作(例如,OOB 数据)。

EDIT1:添加了一条注释,解释使用$(( bs ))-- 从十六进制转换为dd不直接处理十六进制数字(coreutils 和busybox dd 都不是)。


推荐阅读