1 /* 2 * (C) Copyright 2008 Semihalf 3 * 4 * (C) Copyright 2000-2004 5 * DENX Software Engineering 6 * Wolfgang Denk, wd@denx.de 7 * 8 * Updated-by: Prafulla Wadaskar <prafulla@marvell.com> 9 * FIT image specific code abstracted from mkimage.c 10 * some functions added to address abstraction 11 * 12 * All rights reserved. 13 * 14 * SPDX-License-Identifier: GPL-2.0+ 15 */ 16 17 #include "imagetool.h" 18 #include "fit_common.h" 19 #include "mkimage.h" 20 #include <image.h> 21 #include <u-boot/crc.h> 22 23 static image_header_t header; 24 25 /** 26 * fit_handle_file - main FIT file processing function 27 * 28 * fit_handle_file() runs dtc to convert .its to .itb, includes 29 * binary data, updates timestamp property and calculates hashes. 30 * 31 * datafile - .its file 32 * imagefile - .itb file 33 * 34 * returns: 35 * only on success, otherwise calls exit (EXIT_FAILURE); 36 */ 37 static int fit_handle_file(struct image_tool_params *params) 38 { 39 char tmpfile[MKIMAGE_MAX_TMPFILE_LEN]; 40 char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN]; 41 int tfd, destfd = 0; 42 void *dest_blob = NULL; 43 struct stat sbuf; 44 void *ptr; 45 off_t destfd_size = 0; 46 47 /* Flattened Image Tree (FIT) format handling */ 48 debug ("FIT format handling\n"); 49 50 /* call dtc to include binary properties into the tmp file */ 51 if (strlen (params->imagefile) + 52 strlen (MKIMAGE_TMPFILE_SUFFIX) + 1 > sizeof (tmpfile)) { 53 fprintf (stderr, "%s: Image file name (%s) too long, " 54 "can't create tmpfile", 55 params->imagefile, params->cmdname); 56 return (EXIT_FAILURE); 57 } 58 sprintf (tmpfile, "%s%s", params->imagefile, MKIMAGE_TMPFILE_SUFFIX); 59 60 /* We either compile the source file, or use the existing FIT image */ 61 if (params->datafile) { 62 /* dtc -I dts -O dtb -p 500 datafile > tmpfile */ 63 snprintf(cmd, sizeof(cmd), "%s %s %s > %s", 64 MKIMAGE_DTC, params->dtc, params->datafile, tmpfile); 65 debug("Trying to execute \"%s\"\n", cmd); 66 } else { 67 snprintf(cmd, sizeof(cmd), "cp %s %s", 68 params->imagefile, tmpfile); 69 } 70 if (system (cmd) == -1) { 71 fprintf (stderr, "%s: system(%s) failed: %s\n", 72 params->cmdname, cmd, strerror(errno)); 73 goto err_system; 74 } 75 76 if (params->keydest) { 77 destfd = mmap_fdt(params->cmdname, params->keydest, 78 &dest_blob, &sbuf, 1); 79 if (destfd < 0) 80 goto err_keydest; 81 destfd_size = sbuf.st_size; 82 } 83 84 tfd = mmap_fdt(params->cmdname, tmpfile, &ptr, &sbuf, 1); 85 if (tfd < 0) 86 goto err_mmap; 87 88 /* set hashes for images in the blob */ 89 if (fit_add_verification_data(params->keydir, 90 dest_blob, ptr, params->comment, 91 params->require_keys)) { 92 fprintf(stderr, "%s Can't add hashes to FIT blob\n", 93 params->cmdname); 94 goto err_add_hashes; 95 } 96 97 /* for first image creation, add a timestamp at offset 0 i.e., root */ 98 if (params->datafile && fit_set_timestamp(ptr, 0, sbuf.st_mtime)) { 99 fprintf (stderr, "%s: Can't add image timestamp\n", 100 params->cmdname); 101 goto err_add_timestamp; 102 } 103 debug ("Added timestamp successfully\n"); 104 105 munmap ((void *)ptr, sbuf.st_size); 106 close (tfd); 107 if (dest_blob) { 108 munmap(dest_blob, destfd_size); 109 close(destfd); 110 } 111 112 if (rename (tmpfile, params->imagefile) == -1) { 113 fprintf (stderr, "%s: Can't rename %s to %s: %s\n", 114 params->cmdname, tmpfile, params->imagefile, 115 strerror (errno)); 116 unlink (tmpfile); 117 unlink (params->imagefile); 118 return (EXIT_FAILURE); 119 } 120 return (EXIT_SUCCESS); 121 122 err_add_timestamp: 123 err_add_hashes: 124 munmap(ptr, sbuf.st_size); 125 err_mmap: 126 if (dest_blob) 127 munmap(dest_blob, destfd_size); 128 err_keydest: 129 err_system: 130 unlink(tmpfile); 131 return -1; 132 } 133 134 static int fit_check_params(struct image_tool_params *params) 135 { 136 return ((params->dflag && (params->fflag || params->lflag)) || 137 (params->fflag && (params->dflag || params->lflag)) || 138 (params->lflag && (params->dflag || params->fflag))); 139 } 140 141 static struct image_type_params fitimage_params = { 142 .name = "FIT Image support", 143 .header_size = sizeof(image_header_t), 144 .hdr = (void*)&header, 145 .verify_header = fit_verify_header, 146 .print_header = fit_print_contents, 147 .check_image_type = fit_check_image_types, 148 .fflag_handle = fit_handle_file, 149 .set_header = NULL, /* FIT images use DTB header */ 150 .check_params = fit_check_params, 151 }; 152 153 void init_fit_image_type (void) 154 { 155 register_image_type(&fitimage_params); 156 } 157