Problem
ipctool's backup command reads raw MTD partitions via /dev/mtdblockN. On NAND cameras with UBI/UBIFS, this produces dumps that cannot be safely restored to a different chip (or even the same chip after bad blocks change), because:
- Raw MTD dumps include UBI erase counter (EC) and volume ID (VID) headers that encode the physical-to-logical block mapping for the specific chip's bad block layout
- Writing such dumps via
nand write skips bad blocks, shifting all data — UBI's internal mapping becomes inconsistent
- Result: UBIFS finds corrupted data and the camera fails to boot
This was proven on a hi3516av200 camera (128MB SPI NAND, 5 UBI volumes). Raw MTD backup + restore caused:
UBIFS error: bad CRC: calculated 0xde13f664, read 0xb30f1910
Kernel panic - VFS: Unable to mount root fs
The fix: dump UBI volumes (/dev/ubiX_Y) instead of raw MTD, and restore via ubi write which handles bad block mapping internally. Now implemented in defib and documented in the NAND/UBI restore guide.
Current behavior
backup.c:49-61 — cb_mtd_backup() opens /dev/mtdblockN and mmap's raw MTD data. mtd.c:104-121 — open_mtdblock() reads raw NAND including UBI headers. Zero UBI awareness (grep -ri ubi src/ returns nothing).
Proposed changes
1. Detect UBI partitions during backup
In cb_mtd_info() (mtd.c:187), check if the partition has UBI attached by scanning /sys/class/ubi/:
// Check /sys/class/ubi/ubiN/mtd_num to find which UBI device
// is attached to each MTD partition
int find_ubi_for_mtd(int mtd_num) {
DIR *d = opendir("/sys/class/ubi");
if (!d) return -1;
struct dirent *de;
while ((de = readdir(d))) {
if (strncmp(de->d_name, "ubi", 3) != 0) continue;
if (strchr(de->d_name, '_')) continue; // skip ubiN_V entries
char path[128];
snprintf(path, sizeof(path), "/sys/class/ubi/%s/mtd_num", de->d_name);
FILE *f = fopen(path, "r");
if (f) {
int num;
if (fscanf(f, "%d", &num) == 1 && num == mtd_num) {
fclose(f); closedir(d);
int ubi_num;
sscanf(de->d_name, "ubi%d", &ubi_num);
return ubi_num;
}
fclose(f);
}
}
closedir(d);
return -1;
}
2. Dump UBI volumes instead of raw MTD
In cb_mtd_backup() (backup.c:49), when a partition has UBI, read from /dev/ubiN_V instead of /dev/mtdblockN:
int ubi_num = find_ubi_for_mtd(i);
if (ubi_num >= 0) {
// Read /dev/ubiN_0 (first volume)
char vol_path[64];
snprintf(vol_path, sizeof(vol_path), "/dev/ubi%d_0", ubi_num);
int fd = open(vol_path, O_RDONLY);
// Get size from /sys/class/ubi/ubiN_0/data_bytes
// Read volume data (UBIFS image, no UBI headers)
// ...
} else {
// Standard raw MTD dump (current behavior)
char *addr = open_mtdblock(i, &fd, mtd->size, 0);
}
3. Add UBI metadata to YAML
Record which partitions are UBI volumes vs raw MTD. This is essential for proper restore:
rom:
- type: nand
block: 128K
partitions:
- name: boot
size: 0x100000
sha1: b77adba9
dump_type: raw # NEW
- name: rootfs
size: 0x800000
dump_type: ubifs # NEW
ubi_device: 0 # NEW
ubi_volume: 0 # NEW
volume_name: rootfs # NEW (needed for restore via ubi write)
data_bytes: 5206016 # NEW (actual volume data size)
Useful sysfs paths:
/sys/class/ubi/ubiN/mtd_num — which MTD this UBI is attached to
/sys/class/ubi/ubiN_V/name — volume name (e.g., "rootfs")
/sys/class/ubi/ubiN_V/data_bytes — volume data size
/sys/class/ubi/ubiN_V/type — "dynamic" or "static"
4. Support UBI restore
In restore_backup() (backup.c:437), check dump_type and use appropriate method:
dump_type: raw → standard MTD erase+write (current behavior)
dump_type: ubifs → UBI-aware restore:
// Detach UBI, format, reattach, create volume, write UBIFS image
ubidetach -m MTD_NUM
ubiformat /dev/mtdN -y
ubiattach -m MTD_NUM
ubimkvol /dev/ubiN -N VOLNAME -s SIZE
ubiupdatevol /dev/ubiN_0 IMAGE_FILE
These commands may need to be bundled with ipctool or called via system().
5. Files to modify
| File |
Change |
src/mtd.c |
Add find_ubi_for_mtd(), enumerate UBI volumes in cb_mtd_info() |
src/mtd.h |
Add UBI declarations |
src/backup.c |
Modify cb_mtd_backup() for UBI volumes, add dump_type to YAML, UBI-aware restore |
src/backup.h |
Add UBI metadata fields |
Why this matters
NAND cameras are increasingly common (hi3516av200, hi3516dv300, hi3519v101, etc.). Without UBI-aware backups:
- Users cannot safely restore vendor firmware after trying OpenIPC
- Backups uploaded to the cloud are chip-specific and unusable on replacement hardware
- Camera recovery requires serial boot tools instead of simple in-system restore
See the defib NAND/UBI restore guide for full context.
Problem
ipctool's backup command reads raw MTD partitions via
/dev/mtdblockN. On NAND cameras with UBI/UBIFS, this produces dumps that cannot be safely restored to a different chip (or even the same chip after bad blocks change), because:nand writeskips bad blocks, shifting all data — UBI's internal mapping becomes inconsistentThis was proven on a hi3516av200 camera (128MB SPI NAND, 5 UBI volumes). Raw MTD backup + restore caused:
The fix: dump UBI volumes (
/dev/ubiX_Y) instead of raw MTD, and restore viaubi writewhich handles bad block mapping internally. Now implemented in defib and documented in the NAND/UBI restore guide.Current behavior
backup.c:49-61—cb_mtd_backup()opens/dev/mtdblockNand mmap's raw MTD data.mtd.c:104-121—open_mtdblock()reads raw NAND including UBI headers. Zero UBI awareness (grep -ri ubi src/returns nothing).Proposed changes
1. Detect UBI partitions during backup
In
cb_mtd_info()(mtd.c:187), check if the partition has UBI attached by scanning/sys/class/ubi/:2. Dump UBI volumes instead of raw MTD
In
cb_mtd_backup()(backup.c:49), when a partition has UBI, read from/dev/ubiN_Vinstead of/dev/mtdblockN:3. Add UBI metadata to YAML
Record which partitions are UBI volumes vs raw MTD. This is essential for proper restore:
Useful sysfs paths:
/sys/class/ubi/ubiN/mtd_num— which MTD this UBI is attached to/sys/class/ubi/ubiN_V/name— volume name (e.g., "rootfs")/sys/class/ubi/ubiN_V/data_bytes— volume data size/sys/class/ubi/ubiN_V/type— "dynamic" or "static"4. Support UBI restore
In
restore_backup()(backup.c:437), checkdump_typeand use appropriate method:dump_type: raw→ standard MTD erase+write (current behavior)dump_type: ubifs→ UBI-aware restore:system().5. Files to modify
src/mtd.cfind_ubi_for_mtd(), enumerate UBI volumes incb_mtd_info()src/mtd.hsrc/backup.ccb_mtd_backup()for UBI volumes, adddump_typeto YAML, UBI-aware restoresrc/backup.hWhy this matters
NAND cameras are increasingly common (hi3516av200, hi3516dv300, hi3519v101, etc.). Without UBI-aware backups:
See the defib NAND/UBI restore guide for full context.