我有一个非常具体的需求:
部分替换Flash 和的内容以移动MTD分区边界。
当前 map 是:
u-boot 0x000000 0x040000
u-boot-env 0x040000 0x010000
kernel 0x050000 0x230000
initrd 0x280000 0x170000
scripts 0x3f0000 0x010000
filesystem 0x400000 0xbf0000
firmware 0xff0000 0x010000
所需的输出是:
u-boot 0x000000 0x040000
u-boot-env 0x040000 0x010000
kernel 0x050000 0x230000
filesystem 0x280000 0xd70000
firmware 0xff0000 0x010000
这意味着将
initrd
,scripts
和filesystem
折叠到一个区域中,而其他区域则保持独立。问题是这应该从正在运行的系统(使用“旧”配置启动)开始实现。和我应该在重新启动之前重写内核和"new"文件系统。
该系统是嵌入式系统,因此我的操作空间很小(不过,我有SD卡)。
当然,重写后的内核将在其DTB中写入"new"配置。
问题是过渡。
注意:我见过this Question,但是它很老,并且有需要内核补丁的缺点,我想避免这种情况。
注意2:该问题已被标记为删除,因为“与编程无关”。我不同意:我需要在大约14k的设备上执行上述操作,其中大多数设备已经出售给客户,因此任何可行的解决方案至少都应包含脚本。
注意3:如果绝对必要,我什至可以考虑(小的)内核修改(是的,我有办法远程更新内核)。
最佳答案
我有三个想法/建议:
# 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
EDIT1:添加了一条注释,解释了
$(( bs ))
的使用-从十六进制转换,因为dd
不能直接处理十六进制数字(既不是coreutils,也不是busybox dd)。关于linux - 是否可以在运行时调整MTD分区的大小?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57613365/