summaryrefslogtreecommitdiff
path: root/ubi-utils/src/unubi.c
diff options
context:
space:
mode:
Diffstat (limited to 'ubi-utils/src/unubi.c')
-rw-r--r--ubi-utils/src/unubi.c401
1 files changed, 283 insertions, 118 deletions
diff --git a/ubi-utils/src/unubi.c b/ubi-utils/src/unubi.c
index 81db5fa..e0a71a6 100644
--- a/ubi-utils/src/unubi.c
+++ b/ubi-utils/src/unubi.c
@@ -21,7 +21,8 @@
* Drake Dowsett, dowsett@de.ibm.com
*
* 1.2 Removed argp because we want to use uClibc.
- * 1.3 Minor cleanups
+ * 1.3 Minor cleanups.
+ * 1.4 Meanwhile Drake had done a lot of changes, syncing those.
*/
/*
@@ -54,22 +55,30 @@
#define EXEC "unubi"
#define CONTACT "haver@vnet.ibm.com"
-#define VERSION "1.3"
+#define VERSION "1.4"
-static char doc[] = "\nVersion: " VERSION "\n"
- "unubi - analyze raw flash containing UBI data.\n";
+static char doc[] = "\nVersion: " VERSION "\n";
+static int debug = 0;
static const char *optionsstr =
-" OPTIONS\n"
-" -r, --rebuild=<volume-id> Extract and rebuild volume\n"
-"\n"
-" -d, --dir=<output-dir> Specify output directory\n"
+"Extract volumes and/or analysis information from an UBI data file.\n"
+"When no parameters are flagged or given, the default operation is\n"
+"to rebuild all valid complete UBI volumes found within the image.\n"
"\n"
+" OPERATIONS\n"
" -a, --analyze Analyze image\n"
+" -i, --info-table Extract volume information tables\n"
+" -r, --rebuild=<volume-id> Extract and rebuild volume\n"
"\n"
+" OPTIONS\n"
" -b, --blocksize=<block-size> Specify size of eraseblocks in image in bytes\n"
" (default 128KiB)\n"
+" -d, --dir=<output-dir> Specify output directory\n"
+" -D, --debug Enable debug output\n"
+" -s, --headersize=<header-size> Specify size of eraseblock header in image\n"
+" in bytes (default 2048 Byte)\n"
"\n"
+" ADVANCED\n"
" -e, --eb-split Generate individual eraseblock images (all\n"
" eraseblocks)\n"
" -v, --vol-split Generate individual eraseblock images (valid\n"
@@ -78,13 +87,16 @@ static const char *optionsstr =
"\n"
" -?, --help Give this help list\n"
" --usage Give a short usage message\n"
-" --version Print program version\n";
+" --version Print program version\n"
+"\n";
static const char *usage =
-"Usage: unubi [-aevV?] [-r <volume-id>] [-d <output-dir>] [-b <block-size>]\n"
-" [--rebuild=<volume-id>] [--dir=<output-dir>] [--analyze]\n"
-" [--blocksize=<block-size>] [--eb-split] [--vol-split]\n"
-" [--vol-split!] [--help] [--usage] [--version] image-file\n";
+"Usage: unubi [-aievV?] [-r <volume-id>] [-b <block-size>] [-d <output-dir>]\n"
+" [-s <header-size>] [--analyze] [--info-table]\n"
+" [--rebuild=<volume-id>] [--blocksize=<block-size>]\n"
+" [--dir=<output-dir>] [--headersize=<header-size>] [--eb-split]\n"
+" [--vol-split] [--vol-split!] [--help] [--usage] [--version]\n"
+" image-file\n";
#define ERR_MSG(fmt...) \
fprintf(stderr, EXEC ": " fmt)
@@ -101,13 +113,15 @@ static const char *usage =
#define FN_INVAL "%s/eb%04u%s" /* invalid eraseblock */
#define FN_NSURE "%s/eb%04u_%03u_%03u_%03x%s" /* unsure eraseblock */
#define FN_VALID "%s/eb%04u_%03u_%03u_%03x%s" /* valid eraseblock */
-#define FN_VOLSP "%s/vol%03u_%03u_%03u_%04zu" /* split volume */
+#define FN_VOLSP "%s/vol%03u_%03u_%03u_%04u" /* split volume */
#define FN_VOLWH "%s/volume%03u" /* whole volume */
+#define FN_VITBL "%s/vol_info_table%u" /* vol info table */
static uint32_t crc32_table[256];
/* struct args:
* bsize int, blocksize of image blocks
+ * hsize int, eraseblock header size
* analyze flag, when non-zero produce analysis
* eb_split flag, when non-zero output eb####
* note: SPLIT_DATA vs. SPLIT_RAW
@@ -121,13 +135,15 @@ static uint32_t crc32_table[256];
* count_set() and collapse()
*/
struct args {
- uint32_t bsize;
int analyze;
+ int itable;
+ uint32_t *vols;
+ size_t bsize;
+ size_t hsize;
+ char *odir_path;
int eb_split;
int vol_split;
- char *odir_path;
char *img_path;
- uint32_t *vols;
char **options;
};
@@ -164,7 +180,7 @@ str_to_num(char *str)
if ((strcmp(s, "KiB") == 0) || (strcmp(s, "K") == 0) ||
(strcmp(s, "kib") == 0) || (strcmp(s, "k") == 0))
num *= KIB;
- if ((strcmp(s, "MiB") == 0) || (strcmp(s, "M") == 0) ||
+ else if ((strcmp(s, "MiB") == 0) || (strcmp(s, "M") == 0) ||
(strcmp(s, "mib") == 0) || (strcmp(s, "m") == 0))
num *= MIB;
else
@@ -182,56 +198,63 @@ parse_opt(int argc, char **argv, struct args *args)
while (1) {
int key;
- key = getopt_long(argc, argv, "r:d:ab:evV?", long_options, NULL);
+ key = getopt_long(argc, argv, "ab:s:d:Deir:vV?J",
+ long_options, NULL);
if (key == -1)
break;
switch (key) {
- case 'a':
- args->analyze = 1;
- break;
- case 'b':
- args->bsize = str_to_num(optarg);
- break;
- case 'd':
- args->odir_path = optarg;
- break;
- case 'e':
- args->eb_split = SPLIT_RAW;
- break;
- case 'r':
- i = str_to_num(optarg);
- if (i < UBI_MAX_VOLUMES)
- args->vols[str_to_num(optarg)] = 1;
- else {
- ERR_MSG("volume-id out of bounds\n");
- return -1;
- }
- break;
- case 'v':
- if (args->vol_split != SPLIT_RAW)
- args->vol_split = SPLIT_DATA;
- break;
- case 'V':
- args->vol_split = SPLIT_RAW;
- break;
- case '?': /* help */
- fprintf(stderr,
- "Usage: unubi [OPTION...] "
- "image-file\n");
- fprintf(stderr, "%s", doc);
- fprintf(stderr, "%s", optionsstr);
- fprintf(stderr,
- "\nReport bugs to %s\n", CONTACT);
- exit(0);
- break;
- case 'J':
- fprintf(stderr, "%s\n", VERSION);
- exit(0);
- break;
- default:
- fprintf(stderr, "%s", usage);
- exit(-1);
+ case 'a':
+ args->analyze = 1;
+ break;
+ case 'b':
+ args->bsize = str_to_num(optarg);
+ break;
+ case 's':
+ args->hsize = str_to_num(optarg);
+ break;
+ case 'd':
+ args->odir_path = optarg;
+ break;
+ case 'D': /* I wanted to use -v but that was
+ already used ... */
+ debug = 1;
+ break;
+ case 'e':
+ args->eb_split = SPLIT_RAW;
+ break;
+ case 'i':
+ args->itable = 1;
+ break;
+ case 'r':
+ i = str_to_num(optarg);
+ if (i < UBI_MAX_VOLUMES)
+ args->vols[str_to_num(optarg)] = 1;
+ else {
+ ERR_MSG("volume-id out of bounds\n");
+ return -1;
+ }
+ break;
+ case 'v':
+ if (args->vol_split != SPLIT_RAW)
+ args->vol_split = SPLIT_DATA;
+ break;
+ case 'V':
+ args->vol_split = SPLIT_RAW;
+ break;
+ case '?': /* help */
+ fprintf(stderr, "Usage: unubi [OPTION...] "
+ "image-file\n%s%s\nReport bugs to %s\n",
+ doc, optionsstr, CONTACT);
+ exit(0);
+ break;
+ case 'J':
+ fprintf(stderr, "%s\n", VERSION);
+ exit(0);
+ break;
+ default:
+ fprintf(stderr, "%s", usage);
+ exit(-1);
}
}
@@ -287,7 +310,7 @@ collapse(uint32_t *full_array, size_t full_len,
/**
* header_crc: calculate the crc of EITHER a eb_hdr or vid_hdr
- * one of the first to args MUST be NULL, the other is the header
+ * one of the first two args MUST be NULL, the other is the header
* to caculate the crc on
* always returns 0
**/
@@ -391,15 +414,129 @@ extract_data(FILE* fpin, size_t len, const char *path)
/**
+ * extract volume information table from block. saves and reloads fpin
+ * position
+ * returns -1 when a fpos set or get fails, otherwise <= -2 on other
+ * failure and 0 on success
+ **/
+static int
+extract_itable(FILE* fpin, eb_info_t cur, size_t bsize, size_t num,
+ const char* path)
+{
+ char filename[MAXPATH + 1];
+ int rc;
+ size_t i, max;
+ fpos_t temp;
+ FILE* fpout = NULL;
+ struct ubi_vol_tbl_record rec;
+
+ if (fpin == NULL || cur == NULL || path == NULL)
+ return -2;
+
+ /* remember position */
+ rc = fgetpos(fpin, &temp);
+ if (rc < 0)
+ return -1;
+
+ /* jump to top of eraseblock, skip to data section */
+ fsetpos(fpin, &cur->eb_top);
+ if (rc < 0)
+ return -1;
+ fseek(fpin, ubi32_to_cpu(cur->ec.data_offset), SEEK_CUR);
+
+ /* prepare output file */
+ if (ubi32_to_cpu(cur->vid.vol_id) != UBI_LAYOUT_VOL_ID)
+ return -2;
+ memset(filename, 0, MAXPATH + 1);
+ snprintf(filename, MAXPATH, FN_VITBL, path, num);
+ fpout = fopen(filename, "w");
+ if (fpout == NULL)
+ return -2;
+
+ /* loop through entries */
+ fprintf(fpout,
+ "index\trpebs\talign\ttype\tcrc\t\tname\n");
+ max = bsize - ubi32_to_cpu(cur->ec.data_offset);
+ for (i = 0; i < (max / sizeof(rec)); i++) {
+ int blank = 1;
+ char *ptr, *base;
+ char name[UBI_VOL_NAME_MAX + 1];
+ const char *type = "unknown\0";
+ uint32_t crc;
+
+ /* read record */
+ rc = fread(&rec, 1, sizeof(rec), fpin);
+ if (rc == 0)
+ break;
+ if (rc != sizeof(rec)) {
+ ERR_MSG("reading volume information "
+ "table record failed\n");
+ rc = -3;
+ goto exit;
+ }
+
+ /* check crc */
+ crc = clc_crc32(crc32_table, UBI_CRC32_INIT, &rec,
+ UBI_VTBL_RECORD_SIZE_CRC);
+ if (crc != ubi32_to_cpu(rec.crc))
+ continue;
+
+ /* check for empty */
+ base = (char *)&rec;
+ ptr = base;
+ while (blank &&
+ ((unsigned)(ptr - base) < UBI_VTBL_RECORD_SIZE_CRC)) {
+ if (*ptr != 0)
+ blank = 0;
+ ptr++;
+ }
+
+ if (blank)
+ continue;
+
+ /* prep type string */
+ if (rec.vol_type == UBI_VID_DYNAMIC)
+ type = "dynamic\0";
+ else if (rec.vol_type == UBI_VID_STATIC)
+ type = "static\0";
+
+ /* prep name string */
+ rec.name[ubi16_to_cpu(rec.name_len)] = '\0';
+ sprintf(name, "%s", rec.name);
+
+ /* print record line to fpout */
+ fprintf(fpout, "%u\t%u\t%u\t%s\t0x%08x\t%s\n",
+ i,
+ ubi32_to_cpu(rec.reserved_pebs),
+ ubi32_to_cpu(rec.alignment),
+ type,
+ ubi32_to_cpu(rec.crc),
+ name);
+ }
+
+ exit:
+ /* reset position */
+ if (fsetpos(fpin, &temp) < 0)
+ rc = -1;
+
+ if (fpout != NULL)
+ fclose(fpout);
+
+ return rc;
+}
+
+
+/**
* using eb chain, tries to rebuild the data of volume at vol_id, or for all
* the known volumes, if vol_id is NULL;
**/
static int
-rebuild_volume(FILE* fpin, uint32_t *vol_id, eb_info_t *head, const char* path)
+rebuild_volume(FILE* fpin, uint32_t *vol_id, eb_info_t *head, const char* path,
+ size_t block_size, size_t header_size)
{
char filename[MAXPATH];
int rc;
- uint32_t vol, num;
+ uint32_t vol, num, data_size;
FILE* fpout;
eb_info_t cur;
@@ -411,13 +548,13 @@ rebuild_volume(FILE* fpin, uint32_t *vol_id, eb_info_t *head, const char* path)
/* when vol_id is null, then do all */
if (vol_id == NULL) {
cur = *head;
- vol = ubi32_to_cpu(cur->inner.vol_id);
- }
- else {
+ vol = ubi32_to_cpu(cur->vid.vol_id);
+ } else {
vol = *vol_id;
eb_chain_position(head, vol, NULL, &cur);
if (cur == NULL) {
- ERR_MSG("no valid volume %d was found\n", vol);
+ if (debug)
+ ERR_MSG("no valid volume %d was found\n", vol);
return -1;
}
}
@@ -433,7 +570,7 @@ rebuild_volume(FILE* fpin, uint32_t *vol_id, eb_info_t *head, const char* path)
while (cur != NULL) {
size_t i;
- if (ubi32_to_cpu(cur->inner.vol_id) != vol) {
+ if (ubi32_to_cpu(cur->vid.vol_id) != vol) {
/* close out file */
fclose(fpout);
@@ -442,7 +579,7 @@ rebuild_volume(FILE* fpin, uint32_t *vol_id, eb_info_t *head, const char* path)
goto out;
/* begin with next */
- vol = ubi32_to_cpu(cur->inner.vol_id);
+ vol = ubi32_to_cpu(cur->vid.vol_id);
num = 0;
snprintf(filename, MAXPATH, FN_VOLWH, path, vol);
fpout = fopen(filename, "wb");
@@ -453,17 +590,27 @@ rebuild_volume(FILE* fpin, uint32_t *vol_id, eb_info_t *head, const char* path)
}
}
- if (ubi32_to_cpu(cur->inner.lnum) != num) {
- ERR_MSG("missing valid block %d for volume %d\n",
- num, vol);
+ while (num < ubi32_to_cpu(cur->vid.lnum)) {
+ /* FIXME haver: I hope an empty block is
+ written out so that the binary has no holes
+ ... */
+ if (debug)
+ ERR_MSG("missing valid block %d for volume %d\n",
+ num, vol);
+ num++;
}
rc = fsetpos(fpin, &(cur->eb_top));
if (rc < 0)
goto out;
- fseek(fpin, ubi32_to_cpu(cur->outer.data_offset), SEEK_CUR);
+ fseek(fpin, ubi32_to_cpu(cur->ec.data_offset), SEEK_CUR);
- for (i = 0; i < ubi32_to_cpu(cur->inner.data_size); i++) {
+ if (cur->vid.vol_type == UBI_VID_DYNAMIC)
+ data_size = block_size - header_size;
+ else
+ data_size = ubi32_to_cpu(cur->vid.data_size);
+
+ for (i = 0; i < data_size; i++) {
int c = fgetc(fpin);
if (c == EOF) {
ERR_MSG("unexpected EOF while writing: %s\n",
@@ -500,7 +647,7 @@ unubi_volumes(FILE* fpin, uint32_t *vols, size_t vc, struct args *a)
char filename[MAXPATH + 1];
char reason[MAXPATH + 1];
int rc;
- size_t i, count;
+ size_t i, count, itable_num;
/* relations:
* cur ~ head
* next ~ first */
@@ -509,6 +656,7 @@ unubi_volumes(FILE* fpin, uint32_t *vols, size_t vc, struct args *a)
rc = 0;
count = 0;
+ itable_num = 0;
head = NULL;
first = NULL;
next = NULL;
@@ -532,25 +680,25 @@ unubi_volumes(FILE* fpin, uint32_t *vols, size_t vc, struct args *a)
raw_path = FN_INVAL;
/* read erasecounter header */
- rc = fread(&cur->outer, 1, sizeof(cur->outer), fpin);
+ rc = fread(&cur->ec, 1, sizeof(cur->ec), fpin);
if (rc == 0)
goto out; /* EOF */
- if (rc != sizeof(cur->outer)) {
- ERR_MSG("reading ec-hdr failed rc=%d\n", rc);
+ if (rc != sizeof(cur->ec)) {
+ ERR_MSG("reading ec-hdr failed\n");
rc = -1;
goto err;
}
/* check erasecounter header magic */
- if (ubi32_to_cpu(cur->outer.magic) != UBI_EC_HDR_MAGIC) {
+ if (ubi32_to_cpu(cur->ec.magic) != UBI_EC_HDR_MAGIC) {
snprintf(reason, MAXPATH, ".invalid.ec_magic");
goto invalid;
}
/* check erasecounter header crc */
- header_crc(&(cur->outer), NULL, &crc);
+ header_crc(&(cur->ec), NULL, &crc);
- if (ubi32_to_cpu(cur->outer.hdr_crc) != crc) {
+ if (ubi32_to_cpu(cur->ec.hdr_crc) != crc) {
snprintf(reason, MAXPATH, ".invalid.ec_hdr_crc");
goto invalid;
}
@@ -559,27 +707,26 @@ unubi_volumes(FILE* fpin, uint32_t *vols, size_t vc, struct args *a)
rc = fsetpos(fpin, &(cur->eb_top));
if (rc != 0)
goto err;
- fseek(fpin, ubi32_to_cpu(cur->outer.vid_hdr_offset), SEEK_CUR);
-
- /* read erasecounter header */
- rc = fread(&cur->inner, 1, sizeof(cur->inner), fpin);
+ fseek(fpin, ubi32_to_cpu(cur->ec.vid_hdr_offset), SEEK_CUR);
+ rc = fread(&cur->vid, 1, sizeof(cur->vid), fpin);
if (rc == 0)
goto out; /* EOF */
- if (rc != sizeof(cur->inner)) {
- ERR_MSG("reading vid-hdr failed rc=%d\n", rc);
+ if (rc != sizeof(cur->vid)) {
+ ERR_MSG("reading vid-hdr failed\n");
rc = -1;
goto err;
}
- /* empty? */
- if (ubi32_to_cpu(cur->inner.magic) == 0xffffffff) {
+ /* if the magic number is 0xFFFFFFFF, then it's very likely
+ * that the volume is empty */
+ if (ubi32_to_cpu(cur->vid.magic) == 0xffffffff) {
snprintf(reason, MAXPATH, ".empty");
goto invalid;
}
/* vol_id should be in bounds */
- if ((ubi32_to_cpu(cur->inner.vol_id) >= UBI_MAX_VOLUMES) &&
- (ubi32_to_cpu(cur->inner.vol_id) <
+ if ((ubi32_to_cpu(cur->vid.vol_id) >= UBI_MAX_VOLUMES) &&
+ (ubi32_to_cpu(cur->vid.vol_id) <
UBI_INTERNAL_VOL_START)) {
snprintf(reason, MAXPATH, ".invalid");
goto invalid;
@@ -587,25 +734,28 @@ unubi_volumes(FILE* fpin, uint32_t *vols, size_t vc, struct args *a)
raw_path = FN_NSURE;
/* check volume id header magic */
- if (ubi32_to_cpu(cur->inner.magic) != UBI_VID_HDR_MAGIC) {
+ if (ubi32_to_cpu(cur->vid.magic) != UBI_VID_HDR_MAGIC) {
snprintf(reason, MAXPATH, ".invalid.vid_magic");
goto invalid;
}
/* check volume id header crc */
- header_crc(NULL, &(cur->inner), &crc);
- if (ubi32_to_cpu(cur->inner.hdr_crc) != crc) {
+ header_crc(NULL, &(cur->vid), &crc);
+ if (ubi32_to_cpu(cur->vid.hdr_crc) != crc) {
snprintf(reason, MAXPATH, ".invalid.vid_hdr_crc");
goto invalid;
}
- /* check data crc */
- rc = data_crc(fpin, ubi32_to_cpu(cur->inner.data_size), &crc);
- if (rc < 0)
- goto err;
- if (ubi32_to_cpu(cur->inner.data_crc) != crc) {
- snprintf(reason, MAXPATH, ".invalid.data_crc");
- goto invalid;
+ /* check data crc, but only for a static volume */
+ if (cur->vid.vol_type == UBI_VID_STATIC) {
+ rc = data_crc(fpin, ubi32_to_cpu(cur->vid.data_size),
+ &crc);
+ if (rc < 0)
+ goto err;
+ if (ubi32_to_cpu(cur->vid.data_crc) != crc) {
+ snprintf(reason, MAXPATH, ".invalid.data_crc");
+ goto invalid;
+ }
}
/* enlist this vol, it's valid */
@@ -622,6 +772,15 @@ unubi_volumes(FILE* fpin, uint32_t *vols, size_t vc, struct args *a)
goto err;
}
+ /* extract info-table */
+ if (a->itable &&
+ (ubi32_to_cpu(cur->vid.vol_id) == UBI_LAYOUT_VOL_ID)) {
+ extract_itable(fpin, cur, a->bsize,
+ itable_num, a->odir_path);
+ itable_num++;
+ }
+
+ /* split volumes */
if (a->vol_split) {
size_t size = 0;
@@ -631,9 +790,9 @@ unubi_volumes(FILE* fpin, uint32_t *vols, size_t vc, struct args *a)
if (a->vol_split == SPLIT_DATA) {
/* write only data section */
- size = ubi32_to_cpu(cur->inner.data_size);
+ size = ubi32_to_cpu(cur->vid.data_size);
fseek(fpin,
- ubi32_to_cpu(cur->outer.data_offset),
+ ubi32_to_cpu(cur->ec.data_offset),
SEEK_CUR);
}
else if (a->vol_split == SPLIT_RAW)
@@ -642,15 +801,16 @@ unubi_volumes(FILE* fpin, uint32_t *vols, size_t vc, struct args *a)
snprintf(filename, MAXPATH, FN_VOLSP,
a->odir_path,
- ubi32_to_cpu(cur->inner.vol_id),
- ubi32_to_cpu(cur->inner.lnum),
- ubi32_to_cpu(cur->inner.leb_ver), count);
+ ubi32_to_cpu(cur->vid.vol_id),
+ ubi32_to_cpu(cur->vid.lnum),
+ ubi32_to_cpu(cur->vid.leb_ver), count);
rc = extract_data(fpin, size, filename);
if (rc < 0)
goto err;
}
invalid:
+ /* split eraseblocks */
if (a->eb_split) {
/* jump to top of block */
rc = fsetpos(fpin, &(cur->eb_top));
@@ -664,9 +824,9 @@ unubi_volumes(FILE* fpin, uint32_t *vols, size_t vc, struct args *a)
snprintf(filename, MAXPATH, raw_path,
a->odir_path,
count,
- ubi32_to_cpu(cur->inner.vol_id),
- ubi32_to_cpu(cur->inner.lnum),
- ubi32_to_cpu(cur->inner.leb_ver),
+ ubi32_to_cpu(cur->vid.vol_id),
+ ubi32_to_cpu(cur->vid.lnum),
+ ubi32_to_cpu(cur->vid.leb_ver),
reason);
rc = extract_data(fpin, a->bsize, filename);
@@ -704,15 +864,18 @@ unubi_volumes(FILE* fpin, uint32_t *vols, size_t vc, struct args *a)
out:
for (i = 0; i < vc; i++) {
- rc = rebuild_volume(fpin, &vols[i], &head, a->odir_path);
+ rc = rebuild_volume(fpin, &vols[i], &head, a->odir_path,
+ a->bsize, a->hsize);
if (rc < 0)
goto err;
}
/* if there were no volumes specified, rebuild them all,
* UNLESS eb_ or vol_ split or analyze was specified */
- if ((vc == 0) && (!a->eb_split) && (!a->vol_split) && (!a->analyze)) {
- rc = rebuild_volume(fpin, NULL, &head, a->odir_path);
+ if ((vc == 0) && (!a->eb_split) && (!a->vol_split) &&
+ (!a->analyze) && (!a->itable)) {
+ rc = rebuild_volume(fpin, NULL, &head, a->odir_path, a->bsize,
+ a->hsize);
if (rc < 0)
goto err;
}
@@ -722,6 +885,7 @@ unubi_volumes(FILE* fpin, uint32_t *vols, size_t vc, struct args *a)
if (a->analyze)
unubi_analyze(&head, first, a->odir_path);
+
eb_chain_destroy(&head);
eb_chain_destroy(&first);
@@ -751,6 +915,7 @@ main(int argc, char *argv[])
/* setup struct args a */
memset(&a, 0, sizeof(a));
a.bsize = 128 * KIB;
+ a.hsize = 2 * KIB;
a.vols = malloc(sizeof(*a.vols) * UBI_MAX_VOLUMES);
if (a.vols == NULL) {
ERR_MSG("out of memory\n");
@@ -818,8 +983,8 @@ main(int argc, char *argv[])
/* unubi volumes */
rc = unubi_volumes(fpin, vols, vols_len, &a);
if (rc < 0) {
- ERR_MSG("error encountered while working on image file: "
- "%s\n", a.img_path);
+ /* ERR_MSG("error encountered while working on image file: "
+ "%s\n", a.img_path); */
rc = -rc;
goto err;
}