Skip to content

Instantly share code, notes, and snippets.

@Lanchon
Last active February 8, 2024 12:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save Lanchon/fbfbb98e470395ecce23a65021c5f25d to your computer and use it in GitHub Desktop.
Save Lanchon/fbfbb98e470395ecce23a65021c5f25d to your computer and use it in GitHub Desktop.
# Backup and restore UBI partitions and volumes
# Tested on Arris RAC2V1A router
BusyBox v1.22.1 (2018-03-01 14:46:14 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
MM NM MMMMMMM M M
$MMMMM MMMMM MMMMMMMMMMM MMM MMM
MMMMMMMM MM MMMMM. MMMMM:MMMMMM: MMMM MMMMM
MMMM= MMMMMM MMM MMMM MMMMM MMMM MMMMMM MMMM MMMMM'
MMMM= MMMMM MMMM MM MMMMM MMMM MMMM MMMMNMMMMM
MMMM= MMMM MMMMM MMMMM MMMM MMMM MMMMMMMM
MMMM= MMMM MMMMMM MMMMM MMMM MMMM MMMMMMMMM
MMMM= MMMM MMMMM, NMMMMMMMM MMMM MMMM MMMMMMMMMMM
MMMM= MMMM MMMMMM MMMMMMMM MMMM MMMM MMMM MMMMMM
MMMM= MMMM MM MMMM MMMM MMMM MMMM MMMM MMMM
MMMM$ ,MMMMM MMMMM MMMM MMM MMMM MMMMM MMMM MMMM
MMMMMMM: MMMMMMM M MMMMMMMMMMMM MMMMMMM MMMMMMM
MMMMMM MMMMN M MMMMMMMMM MMMM MMMM
MMMM M MMMMMMM M M
M
---------------------------------------------------------------
For those about to rock... (Bleeding Edge, r1121)
---------------------------------------------------------------
root@OpenWrt:~#
# the router has two rootfs ubi partitions for A/B updates:
root@OpenWrt:~# cat /proc/mtd
dev: size erasesize name
mtd0: 00040000 00020000 "0:SBL1"
mtd1: 00140000 00020000 "0:MIBIB"
mtd2: 00140000 00020000 "0:SBL2"
mtd3: 00280000 00020000 "0:SBL3"
mtd4: 00120000 00020000 "0:DDRCONFIG"
mtd5: 00120000 00020000 "0:SSD"
mtd6: 00280000 00020000 "0:TZ"
mtd7: 00280000 00020000 "0:RPM"
mtd8: 00500000 00020000 "0:APPSBL"
mtd9: 00080000 00020000 "0:APPSBLENV"
mtd10: 00140000 00020000 "0:ART"
mtd11: 04000000 00020000 "rootfs"
mtd12: 00060000 00020000 "0:BOOTCONFIG"
mtd13: 00140000 00020000 "0:SBL2_1"
mtd14: 00280000 00020000 "0:SBL3_1"
mtd15: 00120000 00020000 "0:DDRCONFIG_1"
mtd16: 00120000 00020000 "0:SSD_1"
mtd17: 00280000 00020000 "0:TZ_1"
mtd18: 00280000 00020000 "0:RPM_1"
mtd19: 00060000 00020000 "0:BOOTCONFIG1"
mtd20: 00500000 00020000 "0:APPSBL_1"
mtd21: 04000000 00020000 "rootfs_1"
mtd22: 00100000 00020000 "fw_env"
mtd23: 00800000 00020000 "config"
mtd24: 00200000 00020000 "PKI"
mtd25: 00100000 00020000 "scfgmgr"
mtd26: 00008000 00008000 "spi32766.0"
mtd27: 003e0000 0001f000 "kernel"
mtd28: 01e08000 0001f000 "ubi_rootfs"
mtd29: 0001f000 0001f000 "rootfs_data"
mtd30: 00744000 0001f000 "ubi_config"
# each partition has a copy of the 3 volumes needed to bring up the system
# let's check which partition is currently active:
root@OpenWrt:~# dmesg | grep rootfs
[ 0.000000] Kernel command line: console=ttyMSM0,115200n8 ubi.mtd=rootfs root=mtd:ubi_rootfs rootfstype=squashfs
[ 1.869198] 0x000001340000-0x000005340000 : "rootfs"
[ 1.970140] mtd: device 11 (rootfs) set to be root filesystem
[ 1.975401] mtdsplit: no squashfs found in "rootfs"
[ 2.067183] 0x000006400000-0x00000a400000 : "rootfs_1"
[ 2.939119] UBI: attached mtd11 (name "rootfs", size 64 MiB) to ubi0
# the active rootfs ubi is: mtd11: 04000000 00020000 "rootfs"
# it is attached to ubi0, let's see:
root@OpenWrt:/config# ubinfo -a
UBI version: 1
Count of UBI devices: 2
UBI control device major/minor: 10:60
Present UBI devices: ubi0, ubi1
ubi0
Volumes count: 3
Logical eraseblock size: 126976 bytes, 124.0 KiB
Total amount of logical eraseblocks: 512 (65011712 bytes, 62.0 MiB)
Amount of available logical eraseblocks: 227 (28823552 bytes, 27.5 MiB)
Maximum count of volumes 128
Count of bad physical eraseblocks: 0
Count of reserved physical eraseblocks: 0
Current maximum erase counter value: 72
Minimum input/output unit size: 2048 bytes
Character device major/minor: 249:0
Present volumes: 0, 1, 2
Volume ID: 0 (on ubi0)
Type: dynamic
Alignment: 1
Size: 32 LEBs (4063232 bytes, 3.9 MiB)
State: OK
Name: kernel
Character device major/minor: 249:1
-----------------------------------
Volume ID: 1 (on ubi0)
Type: dynamic
Alignment: 1
Size: 248 LEBs (31490048 bytes, 30.0 MiB)
State: OK
Name: ubi_rootfs
Character device major/minor: 249:2
-----------------------------------
Volume ID: 2 (on ubi0)
Type: dynamic
Alignment: 1
Size: 1 LEBs (126976 bytes, 124.0 KiB)
State: OK
Name: rootfs_data
Character device major/minor: 249:3
===================================
ubi1
Volumes count: 1
Logical eraseblock size: 126976 bytes, 124.0 KiB
Total amount of logical eraseblocks: 64 (8126464 bytes, 7.8 MiB)
Amount of available logical eraseblocks: 0 (0 bytes)
Maximum count of volumes 128
Count of bad physical eraseblocks: 0
Count of reserved physical eraseblocks: 0
Current maximum erase counter value: 9
Minimum input/output unit size: 2048 bytes
Character device major/minor: 244:0
Present volumes: 0
Volume ID: 0 (on ubi1)
Type: dynamic
Alignment: 1
Size: 60 LEBs (7618560 bytes, 7.3 MiB)
State: OK
Name: ubi_config
Character device major/minor: 244:1
# the inactive rootfs ubi is: mtd21: 04000000 00020000 "rootfs_1"
# we will use the inactive partition for testing
# it is not attached, so let's attach it now:
root@OpenWrt:~# ubiattach -m 21
UBI device number 2, total 512 LEBs (65011712 bytes, 62.0 MiB), available 227 LEBs (28823552 bytes, 27.5 MiB), LEB size 126976 bytes (124.0 KiB)
# it was attached to ubi2:
root@OpenWrt:~# ubinfo -a -d 2
ubi2
Volumes count: 3
Logical eraseblock size: 126976 bytes, 124.0 KiB
Total amount of logical eraseblocks: 512 (65011712 bytes, 62.0 MiB)
Amount of available logical eraseblocks: 227 (28823552 bytes, 27.5 MiB)
Maximum count of volumes 128
Count of bad physical eraseblocks: 0
Count of reserved physical eraseblocks: 0
Current maximum erase counter value: 2
Minimum input/output unit size: 2048 bytes
Character device major/minor: 243:0
Present volumes: 0, 1, 2
Volume ID: 0 (on ubi2)
Type: dynamic
Alignment: 1
Size: 32 LEBs (4063232 bytes, 3.9 MiB)
State: OK
Name: kernel
Character device major/minor: 243:1
-----------------------------------
Volume ID: 1 (on ubi2)
Type: dynamic
Alignment: 1
Size: 248 LEBs (31490048 bytes, 30.0 MiB)
State: OK
Name: ubi_rootfs
Character device major/minor: 243:2
-----------------------------------
Volume ID: 2 (on ubi2)
Type: dynamic
Alignment: 1
Size: 1 LEBs (126976 bytes, 124.0 KiB)
State: OK
Name: rootfs_data
Character device major/minor: 243:3
# so we have the two rootfs ubis (A/B) attached
# verify that the two sets of volumes have the same contents:
root@OpenWrt:~# cmp /dev/ubi0_0 /dev/ubi2_0
root@OpenWrt:~# cmp /dev/ubi0_1 /dev/ubi2_1
root@OpenWrt:~# cmp /dev/ubi0_2 /dev/ubi2_2
### UBI Volume Backup
# let's backup a volume of the inactive ubi2:
# IMPORTANT: (i suppose) the ubi volume must not be mounted!
root@OpenWrt:~# mkdir /tmp/ubibak
root@OpenWrt:~# cd /tmp/ubibak
root@OpenWrt:/tmp/ubibak# dd if=/dev/ubi2_0 of=ubi2_0 bs=1M
3+1 records in
3+1 records out
root@OpenWrt:/tmp/ubibak# cmp /dev/ubi2_0 ubi2_0
root@OpenWrt:/tmp/ubibak# md5sum /dev/ubi2_0 ubi2_0
eee27de10678f707260f90a3ac35ff0c /dev/ubi2_0
eee27de10678f707260f90a3ac35ff0c ubi2_0
# now wipe out the volume:
root@OpenWrt:/tmp/ubibak# ubiupdatevol /dev/ubi2_0 -t
root@OpenWrt:/tmp/ubibak# md5sum /dev/ubi2_0 ubi2_0
faa1e5da33e5779508737687b3d68778 /dev/ubi2_0
eee27de10678f707260f90a3ac35ff0c ubi2_0
# the data is gone, let's restore the backup:
# IMPORTANT: (i suppose) the ubi volume must not be mounted!
root@OpenWrt:/tmp/ubibak# ubiupdatevol /dev/ubi2_0 ubi2_0
root@OpenWrt:/tmp/ubibak# md5sum /dev/ubi2_0 ubi2_0
eee27de10678f707260f90a3ac35ff0c /dev/ubi2_0
eee27de10678f707260f90a3ac35ff0c ubi2_0
rm ubi2_0
# success!
### UBI Partition Backup
# now let's try a full ubi partition backup:
root@OpenWrt:/tmp/ubibak# md5sum /dev/ubi2_*
eee27de10678f707260f90a3ac35ff0c /dev/ubi2_0
c0edea192786289b6d6acc1fb60b3eb2 /dev/ubi2_1
f7d566ac0d14fb993db66ed5ea370797 /dev/ubi2_2
root@OpenWrt:/tmp/ubibak# md5sum /dev/ubi0_*
eee27de10678f707260f90a3ac35ff0c /dev/ubi0_0
c0edea192786289b6d6acc1fb60b3eb2 /dev/ubi0_1
f7d566ac0d14fb993db66ed5ea370797 /dev/ubi0_2
# IMPORTANT: (i suppose) the ubi partition must not be attached!
root@OpenWrt:/tmp/ubibak# ubidetach -m 21
# IMPORTANT: use the char device to backup the mtd partition! (not the mtdblock device)
root@OpenWrt:/tmp/ubibak# dd if=/dev/mtd21 of=mtd21 bs=1M
64+0 records in
64+0 records out
# wipe out the partition:
# IMPORTANT: do not use flash_erase! it might shorten the flash memory life span
# flash_erase wipes the erase counters that needed for correct wear leveling
root@OpenWrt:/tmp/ubibak# ubiformat /dev/mtd21
ubiformat: mtd21 (nand), size 67108864 bytes (64.0 MiB), 512 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 511 -- 100 % complete
ubiformat: 512 eraseblocks have valid erase counter, mean value is 0
ubiformat: formatting eraseblock 511 -- 100 % complete
# check that the partition is actually gone:
root@OpenWrt:/tmp/ubibak# ubiattach -m 21
UBI device number 2, total 512 LEBs (65011712 bytes, 62.0 MiB), available 508 LEBs (64503808 bytes, 61.5 MiB), LEB size 126976 bytes (124.0 KiB)
root@OpenWrt:/tmp/ubibak# ubinfo -a -d 2
ubi2
Volumes count: 0
Logical eraseblock size: 126976 bytes, 124.0 KiB
Total amount of logical eraseblocks: 512 (65011712 bytes, 62.0 MiB)
Amount of available logical eraseblocks: 508 (64503808 bytes, 61.5 MiB)
Maximum count of volumes 128
Count of bad physical eraseblocks: 0
Count of reserved physical eraseblocks: 0
Current maximum erase counter value: 14
Minimum input/output unit size: 2048 bytes
Character device major/minor: 243:0
# now let's restore the backup:
# IMPORTANT: (i suppose) the ubi partition must not be attached!
# IMPORTANT: do not use nandwrite! backups may contain erased pages and nandwrite writes those as data
# if you have to use nandwrite, see the --space-fixup flag that triggers the UBIFS 'free space fixup' procedure
root@OpenWrt:/tmp/ubibak# ubidetach -m 21
root@OpenWrt:/tmp/ubibak# ubiformat /dev/mtd21 -f mtd21
ubiformat: mtd21 (nand), size 67108864 bytes (64.0 MiB), 512 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 511 -- 100 % complete
ubiformat: 512 eraseblocks have valid erase counter, mean value is 1
ubiformat: flashing eraseblock 511 -- 100 % complete
# and check the contents:
root@OpenWrt:/tmp/ubibak# ubiattach -m 21
UBI device number 2, total 512 LEBs (65011712 bytes, 62.0 MiB), available 227 LEBs (28823552 bytes, 27.5 MiB), LEB size 126976 bytes (124.0 KiB)
root@OpenWrt:/tmp/ubibak# ubinfo -a -d 2
ubi2
Volumes count: 3
Logical eraseblock size: 126976 bytes, 124.0 KiB
Total amount of logical eraseblocks: 512 (65011712 bytes, 62.0 MiB)
Amount of available logical eraseblocks: 227 (28823552 bytes, 27.5 MiB)
Maximum count of volumes 128
Count of bad physical eraseblocks: 0
Count of reserved physical eraseblocks: 0
Current maximum erase counter value: 15
Minimum input/output unit size: 2048 bytes
Character device major/minor: 243:0
Present volumes: 0, 1, 2
Volume ID: 0 (on ubi2)
Type: dynamic
Alignment: 1
Size: 32 LEBs (4063232 bytes, 3.9 MiB)
State: OK
Name: kernel
Character device major/minor: 243:1
-----------------------------------
Volume ID: 1 (on ubi2)
Type: dynamic
Alignment: 1
Size: 248 LEBs (31490048 bytes, 30.0 MiB)
State: OK
Name: ubi_rootfs
Character device major/minor: 243:2
-----------------------------------
Volume ID: 2 (on ubi2)
Type: dynamic
Alignment: 1
Size: 1 LEBs (126976 bytes, 124.0 KiB)
State: OK
Name: rootfs_data
Character device major/minor: 243:3
# the volumes are back, let's check the contents:
root@OpenWrt:/tmp/ubibak# md5sum /dev/ubi2_*
eee27de10678f707260f90a3ac35ff0c /dev/ubi2_0
c0edea192786289b6d6acc1fb60b3eb2 /dev/ubi2_1
f7d566ac0d14fb993db66ed5ea370797 /dev/ubi2_2
root@OpenWrt:/tmp/ubibak# md5sum /dev/ubi0_*
eee27de10678f707260f90a3ac35ff0c /dev/ubi0_0
c0edea192786289b6d6acc1fb60b3eb2 /dev/ubi0_1
f7d566ac0d14fb993db66ed5ea370797 /dev/ubi0_2
# success!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment