diff --git a/fdtextract.c b/fdtextract.c index 7188b6ebc0a9b1445624b6e4fe248a1ca40087f0..e8328893e62c64e7bb60caaa7f2a1dbab2df5789 100644 --- a/fdtextract.c +++ b/fdtextract.c @@ -1,5 +1,5 @@ /* - * dumpimage -- Tool to extract sub images from FIT image. + * fdtextract -- Tool to extract sub images from FIT image. * * Copyright (C) 2021 IOPSYS Software Solutions AB. All rights reserved. * @@ -89,12 +89,19 @@ static int list_images(char *buf) } /* Extract an image embedded in the FIT. */ -static int extract_image(char *buf, char *name, char *out) +static int extract_image(const char *file, char *name, char *out) { char path[MAX_PATH_LEN]; int noffset, fd, count; unsigned int data_size, data_offset; const fdt32_t *val; + char *buf; + size_t len; + + buf = utilfdt_read(file, &len); + if (!buf) { + die("could not read: %s\n", file); + } snprintf(path, MAX_PATH_LEN, "/images/%s", name); noffset = fdt_path_offset(buf, path); @@ -205,6 +212,38 @@ static int get_attribute(char *buf, char *name) return 0; } +char *read_header(const char *file) +{ + char *buf; + int fd, total_size; + size_t len; + + fd = open(file, O_RDONLY); + if (fd < 0) + return NULL; + + /* Read minimal static struct */ + buf = malloc(FDT_V1_SIZE); + if (!buf) + return NULL; + + len = read(fd, buf, FDT_V1_SIZE); + if (len < FDT_V1_SIZE) + return NULL; + + /* Read rest of header */ + total_size = fdt_totalsize(buf); + buf = realloc(buf, total_size); + if (!buf) + return NULL; + + len = read(fd, buf + FDT_V1_SIZE, total_size - FDT_V1_SIZE); + if (len < total_size - FDT_V1_SIZE) + return NULL; + + return buf; +} + int main(int argc, char *argv[]) { const char *file; @@ -212,7 +251,6 @@ int main(int argc, char *argv[]) char *buf, *name = NULL, *out = NULL; bool list = false, extract = false, hash = false, attribute = false; - size_t len; while ((opt = util_getopt_long()) != EOF) { switch (opt) { @@ -242,26 +280,28 @@ int main(int argc, char *argv[]) usage("missing input filename"); file = argv[optind]; - buf = utilfdt_read(file, &len); + buf = read_header(file); if (!buf) { - die("could not read: %s\n", file); + die("could not read header from: %s\n", file); } if (fdt_check_header(buf)) { die("Bad header in %s\n", file); } + /* Pass the pointer to the header to read attributes. */ if (list) ret = list_images(buf); - if (extract) - ret = extract_image(buf, name, out); - if (hash) ret = get_hash(buf, name); if (attribute) ret = get_attribute(buf, name); + /* Let extract image read the entire file. */ + if (extract) + ret = extract_image(file, name, out); + return ret; }