Newer
Older
/*
* dumpimage -- Tool to extract sub images from FIT image.
*
* Copyright (C) 2021 IOPSYS Software Solutions AB. All rights reserved.
*
* Author: jonas.hoglund@iopsys.eu
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
static const char usage_synopsis[] = "fdtextract [options] <file>";
static const char usage_short_opts[] = "le:o:s:" USAGE_COMMON_SHORT_OPTS;
static struct option const usage_long_opts[] = {
{"list", no_argument, NULL, 'l'},
{"extract", a_argument, NULL, 'e'},
{"out", a_argument, NULL, 'o'},
USAGE_COMMON_LONG_OPTS
};
static const char * const usage_opts_help[] = {
"List images embedded in FIT",
"Extract image from FIT",
static int list_images(char *buf)
{
int ndepth = 0, count = 0, noffset;
const char *name;
noffset = fdt_next_node(buf, noffset, &ndepth);
while (ndepth > 0) {
if (ndepth == 1) {
name = fdt_get_name(buf, noffset, NULL);
printf("[%d]: %s\n", count, name);
count++;
}
noffset = fdt_next_node(buf, noffset, &ndepth);
}
static int extract_image(char *buf, char *name, char *out)
unsigned int data_size, data_offset;
const fdt32_t *val;
if (!out) {
printf("Error: please specify output file name.\n");
return -1;
}
snprintf(path, MAX_PATH_LEN, "/images/%s", name);
noffset = fdt_path_offset(buf, path);
if (noffset < 0) {
printf("Error: could not find image: %s.\n", name);
return -1;
}
/* Get offset of image. Try both relative and absolute offset. */
val = fdt_getprop(buf, noffset, "data-offset", NULL);
if(val) {
/* Relative offset */
data_offset = fdt32_to_cpu(*val);
data_offset += ((fdt_totalsize(buf) + 3) & ~3);
} else {
/* Absolute offset */
val = fdt_getprop(buf, noffset, "data-position", NULL);
if (!val) {
printf("Error: could get offset of image: %s.\n", name);
return -1;
}
data_offset = fdt32_to_cpu(*val);
}
/* Size */
val = fdt_getprop(buf, noffset, "data-size", NULL);
if (!val) {
printf("Error: could get size of image: %s.\n", name);
return -1;
}
data_size = fdt32_to_cpu(*val);
fd = open(out, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd < 0) {
printf("Error opening output file %s.\n", out);
return errno;
}
count = write(fd, buf + data_offset, data_size);
if (count < data_size) {
printf("Error writing output file %s.\n", out);
return errno;
}
static int get_hash(char *buf, char *name)
{
char path[MAX_PATH_LEN];
int noffset, i;
uint8_t *val;
snprintf(path, MAX_PATH_LEN, "/images/%s/hash-1", name);
noffset = fdt_path_offset(buf, path);
if (noffset < 0) {
printf("Error: could not find image hash: %s.\n", name);
return -1;
}
val = (uint8_t *)fdt_getprop(buf, noffset, "value", NULL);
for (i=0; i<SHA_256_LEN; i++)
printf("%x", val[i]);
printf("\n");
}
while ((opt = util_getopt_long()) != EOF) {
switch (opt) {
case_USAGE_COMMON_FLAGS
case 'l':
list = true;
break;
case 'e':
extract = true;
name = optarg;
break;
case 'o':
out = optarg;
case 's':
hash = true;
name = optarg;
break;
}
}
if (optind != argc - 1)
usage("missing input filename");
file = argv[optind];
buf = utilfdt_read(file, &len);
if (!buf) {
die("could not read: %s\n", file);
}
if (list)
list_images(buf);
if (extract)