189a4d6b1SPrafulla Wadaskar /* 289a4d6b1SPrafulla Wadaskar * (C) Copyright 2008 Semihalf 389a4d6b1SPrafulla Wadaskar * 489a4d6b1SPrafulla Wadaskar * (C) Copyright 2000-2004 589a4d6b1SPrafulla Wadaskar * DENX Software Engineering 689a4d6b1SPrafulla Wadaskar * Wolfgang Denk, wd@denx.de 789a4d6b1SPrafulla Wadaskar * 889a4d6b1SPrafulla Wadaskar * Updated-by: Prafulla Wadaskar <prafulla@marvell.com> 989a4d6b1SPrafulla Wadaskar * FIT image specific code abstracted from mkimage.c 1089a4d6b1SPrafulla Wadaskar * some functions added to address abstraction 1189a4d6b1SPrafulla Wadaskar * 1289a4d6b1SPrafulla Wadaskar * All rights reserved. 1389a4d6b1SPrafulla Wadaskar * 1489a4d6b1SPrafulla Wadaskar * This program is free software; you can redistribute it and/or 1589a4d6b1SPrafulla Wadaskar * modify it under the terms of the GNU General Public License as 1689a4d6b1SPrafulla Wadaskar * published by the Free Software Foundation; either version 2 of 1789a4d6b1SPrafulla Wadaskar * the License, or (at your option) any later version. 1889a4d6b1SPrafulla Wadaskar * 1989a4d6b1SPrafulla Wadaskar * This program is distributed in the hope that it will be useful, 2089a4d6b1SPrafulla Wadaskar * but WITHOUT ANY WARRANTY; without even the implied warranty of 2189a4d6b1SPrafulla Wadaskar * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2289a4d6b1SPrafulla Wadaskar * GNU General Public License for more details. 2389a4d6b1SPrafulla Wadaskar * 2489a4d6b1SPrafulla Wadaskar * You should have received a copy of the GNU General Public License 2589a4d6b1SPrafulla Wadaskar * along with this program; if not, write to the Free Software 2689a4d6b1SPrafulla Wadaskar * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 2789a4d6b1SPrafulla Wadaskar * MA 02111-1307 USA 2889a4d6b1SPrafulla Wadaskar */ 2989a4d6b1SPrafulla Wadaskar 3089a4d6b1SPrafulla Wadaskar #include "mkimage.h" 3189a4d6b1SPrafulla Wadaskar #include <image.h> 3289a4d6b1SPrafulla Wadaskar #include <u-boot/crc.h> 3389a4d6b1SPrafulla Wadaskar 3489a4d6b1SPrafulla Wadaskar static image_header_t header; 3589a4d6b1SPrafulla Wadaskar 3689a4d6b1SPrafulla Wadaskar static int fit_verify_header (unsigned char *ptr, int image_size, 3789a4d6b1SPrafulla Wadaskar struct mkimage_params *params) 3889a4d6b1SPrafulla Wadaskar { 3989a4d6b1SPrafulla Wadaskar return fdt_check_header ((void *)ptr); 4089a4d6b1SPrafulla Wadaskar } 4189a4d6b1SPrafulla Wadaskar 4289a4d6b1SPrafulla Wadaskar static int fit_check_image_types (uint8_t type) 4389a4d6b1SPrafulla Wadaskar { 4489a4d6b1SPrafulla Wadaskar if (type == IH_TYPE_FLATDT) 4589a4d6b1SPrafulla Wadaskar return EXIT_SUCCESS; 4689a4d6b1SPrafulla Wadaskar else 4789a4d6b1SPrafulla Wadaskar return EXIT_FAILURE; 4889a4d6b1SPrafulla Wadaskar } 4989a4d6b1SPrafulla Wadaskar 50aa6d6db4SSimon Glass int mmap_fdt(struct mkimage_params *params, const char *fname, void **blobp, 51aa6d6db4SSimon Glass struct stat *sbuf) 52aa6d6db4SSimon Glass { 53aa6d6db4SSimon Glass void *ptr; 54aa6d6db4SSimon Glass int fd; 55aa6d6db4SSimon Glass 56aa6d6db4SSimon Glass /* Load FIT blob into memory (we need to write hashes/signatures) */ 57aa6d6db4SSimon Glass fd = open(fname, O_RDWR | O_BINARY); 58aa6d6db4SSimon Glass 59aa6d6db4SSimon Glass if (fd < 0) { 60aa6d6db4SSimon Glass fprintf(stderr, "%s: Can't open %s: %s\n", 61aa6d6db4SSimon Glass params->cmdname, fname, strerror(errno)); 62aa6d6db4SSimon Glass unlink(fname); 63aa6d6db4SSimon Glass return -1; 64aa6d6db4SSimon Glass } 65aa6d6db4SSimon Glass 66aa6d6db4SSimon Glass if (fstat(fd, sbuf) < 0) { 67aa6d6db4SSimon Glass fprintf(stderr, "%s: Can't stat %s: %s\n", 68aa6d6db4SSimon Glass params->cmdname, fname, strerror(errno)); 69aa6d6db4SSimon Glass unlink(fname); 70aa6d6db4SSimon Glass return -1; 71aa6d6db4SSimon Glass } 72aa6d6db4SSimon Glass 73aa6d6db4SSimon Glass ptr = mmap(0, sbuf->st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 74aa6d6db4SSimon Glass if (ptr == MAP_FAILED) { 75aa6d6db4SSimon Glass fprintf(stderr, "%s: Can't read %s: %s\n", 76aa6d6db4SSimon Glass params->cmdname, fname, strerror(errno)); 77aa6d6db4SSimon Glass unlink(fname); 78aa6d6db4SSimon Glass return -1; 79aa6d6db4SSimon Glass } 80aa6d6db4SSimon Glass 81aa6d6db4SSimon Glass /* check if ptr has a valid blob */ 82aa6d6db4SSimon Glass if (fdt_check_header(ptr)) { 83aa6d6db4SSimon Glass fprintf(stderr, "%s: Invalid FIT blob\n", params->cmdname); 84aa6d6db4SSimon Glass unlink(fname); 85aa6d6db4SSimon Glass return -1; 86aa6d6db4SSimon Glass } 87aa6d6db4SSimon Glass 88aa6d6db4SSimon Glass *blobp = ptr; 89aa6d6db4SSimon Glass return fd; 90aa6d6db4SSimon Glass } 91aa6d6db4SSimon Glass 9289a4d6b1SPrafulla Wadaskar /** 9389a4d6b1SPrafulla Wadaskar * fit_handle_file - main FIT file processing function 9489a4d6b1SPrafulla Wadaskar * 9589a4d6b1SPrafulla Wadaskar * fit_handle_file() runs dtc to convert .its to .itb, includes 9689a4d6b1SPrafulla Wadaskar * binary data, updates timestamp property and calculates hashes. 9789a4d6b1SPrafulla Wadaskar * 9889a4d6b1SPrafulla Wadaskar * datafile - .its file 9989a4d6b1SPrafulla Wadaskar * imagefile - .itb file 10089a4d6b1SPrafulla Wadaskar * 10189a4d6b1SPrafulla Wadaskar * returns: 10289a4d6b1SPrafulla Wadaskar * only on success, otherwise calls exit (EXIT_FAILURE); 10389a4d6b1SPrafulla Wadaskar */ 10489a4d6b1SPrafulla Wadaskar static int fit_handle_file (struct mkimage_params *params) 10589a4d6b1SPrafulla Wadaskar { 10689a4d6b1SPrafulla Wadaskar char tmpfile[MKIMAGE_MAX_TMPFILE_LEN]; 10789a4d6b1SPrafulla Wadaskar char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN]; 108*e29495d3SSimon Glass int tfd, destfd = 0; 109*e29495d3SSimon Glass void *dest_blob = NULL; 11089a4d6b1SPrafulla Wadaskar struct stat sbuf; 111aa6d6db4SSimon Glass void *ptr; 112*e29495d3SSimon Glass off_t destfd_size = 0; 11389a4d6b1SPrafulla Wadaskar 11489a4d6b1SPrafulla Wadaskar /* Flattened Image Tree (FIT) format handling */ 11589a4d6b1SPrafulla Wadaskar debug ("FIT format handling\n"); 11689a4d6b1SPrafulla Wadaskar 11789a4d6b1SPrafulla Wadaskar /* call dtc to include binary properties into the tmp file */ 11889a4d6b1SPrafulla Wadaskar if (strlen (params->imagefile) + 11989a4d6b1SPrafulla Wadaskar strlen (MKIMAGE_TMPFILE_SUFFIX) + 1 > sizeof (tmpfile)) { 12089a4d6b1SPrafulla Wadaskar fprintf (stderr, "%s: Image file name (%s) too long, " 12189a4d6b1SPrafulla Wadaskar "can't create tmpfile", 12289a4d6b1SPrafulla Wadaskar params->imagefile, params->cmdname); 12389a4d6b1SPrafulla Wadaskar return (EXIT_FAILURE); 12489a4d6b1SPrafulla Wadaskar } 12589a4d6b1SPrafulla Wadaskar sprintf (tmpfile, "%s%s", params->imagefile, MKIMAGE_TMPFILE_SUFFIX); 12689a4d6b1SPrafulla Wadaskar 127ee7c0fc7SLars Rasmusson /* dtc -I dts -O dtb -p 500 datafile > tmpfile */ 12889a4d6b1SPrafulla Wadaskar sprintf (cmd, "%s %s %s > %s", 12989a4d6b1SPrafulla Wadaskar MKIMAGE_DTC, params->dtc, params->datafile, tmpfile); 13089a4d6b1SPrafulla Wadaskar debug ("Trying to execute \"%s\"\n", cmd); 13189a4d6b1SPrafulla Wadaskar if (system (cmd) == -1) { 13289a4d6b1SPrafulla Wadaskar fprintf (stderr, "%s: system(%s) failed: %s\n", 13389a4d6b1SPrafulla Wadaskar params->cmdname, cmd, strerror(errno)); 134aa6d6db4SSimon Glass goto err_system; 13589a4d6b1SPrafulla Wadaskar } 13689a4d6b1SPrafulla Wadaskar 137*e29495d3SSimon Glass if (params->keydest) { 138*e29495d3SSimon Glass destfd = mmap_fdt(params, params->keydest, &dest_blob, &sbuf); 139*e29495d3SSimon Glass if (destfd < 0) 140*e29495d3SSimon Glass goto err_keydest; 141*e29495d3SSimon Glass destfd_size = sbuf.st_size; 142*e29495d3SSimon Glass } 143*e29495d3SSimon Glass 144aa6d6db4SSimon Glass tfd = mmap_fdt(params, tmpfile, &ptr, &sbuf); 145aa6d6db4SSimon Glass if (tfd < 0) 146aa6d6db4SSimon Glass goto err_mmap; 14789a4d6b1SPrafulla Wadaskar 14889a4d6b1SPrafulla Wadaskar /* set hashes for images in the blob */ 149*e29495d3SSimon Glass if (fit_add_verification_data(params->keydir, dest_blob, ptr, 150*e29495d3SSimon Glass NULL, 0)) { 15189a4d6b1SPrafulla Wadaskar fprintf (stderr, "%s Can't add hashes to FIT blob", 15289a4d6b1SPrafulla Wadaskar params->cmdname); 153aa6d6db4SSimon Glass goto err_add_hashes; 15489a4d6b1SPrafulla Wadaskar } 15589a4d6b1SPrafulla Wadaskar 15689a4d6b1SPrafulla Wadaskar /* add a timestamp at offset 0 i.e., root */ 15789a4d6b1SPrafulla Wadaskar if (fit_set_timestamp (ptr, 0, sbuf.st_mtime)) { 15889a4d6b1SPrafulla Wadaskar fprintf (stderr, "%s: Can't add image timestamp\n", 15989a4d6b1SPrafulla Wadaskar params->cmdname); 160aa6d6db4SSimon Glass goto err_add_timestamp; 16189a4d6b1SPrafulla Wadaskar } 16289a4d6b1SPrafulla Wadaskar debug ("Added timestamp successfully\n"); 16389a4d6b1SPrafulla Wadaskar 16489a4d6b1SPrafulla Wadaskar munmap ((void *)ptr, sbuf.st_size); 16589a4d6b1SPrafulla Wadaskar close (tfd); 166*e29495d3SSimon Glass if (dest_blob) { 167*e29495d3SSimon Glass munmap(dest_blob, destfd_size); 168*e29495d3SSimon Glass close(destfd); 169*e29495d3SSimon Glass } 17089a4d6b1SPrafulla Wadaskar 17189a4d6b1SPrafulla Wadaskar if (rename (tmpfile, params->imagefile) == -1) { 17289a4d6b1SPrafulla Wadaskar fprintf (stderr, "%s: Can't rename %s to %s: %s\n", 17389a4d6b1SPrafulla Wadaskar params->cmdname, tmpfile, params->imagefile, 17489a4d6b1SPrafulla Wadaskar strerror (errno)); 17589a4d6b1SPrafulla Wadaskar unlink (tmpfile); 17689a4d6b1SPrafulla Wadaskar unlink (params->imagefile); 17789a4d6b1SPrafulla Wadaskar return (EXIT_FAILURE); 17889a4d6b1SPrafulla Wadaskar } 17989a4d6b1SPrafulla Wadaskar return (EXIT_SUCCESS); 180aa6d6db4SSimon Glass 181aa6d6db4SSimon Glass err_add_timestamp: 182aa6d6db4SSimon Glass err_add_hashes: 183aa6d6db4SSimon Glass munmap(ptr, sbuf.st_size); 184aa6d6db4SSimon Glass err_mmap: 185*e29495d3SSimon Glass if (dest_blob) 186*e29495d3SSimon Glass munmap(dest_blob, destfd_size); 187*e29495d3SSimon Glass err_keydest: 188aa6d6db4SSimon Glass err_system: 189aa6d6db4SSimon Glass unlink(tmpfile); 190aa6d6db4SSimon Glass return -1; 19189a4d6b1SPrafulla Wadaskar } 19289a4d6b1SPrafulla Wadaskar 19389a4d6b1SPrafulla Wadaskar static int fit_check_params (struct mkimage_params *params) 19489a4d6b1SPrafulla Wadaskar { 19589a4d6b1SPrafulla Wadaskar return ((params->dflag && (params->fflag || params->lflag)) || 19689a4d6b1SPrafulla Wadaskar (params->fflag && (params->dflag || params->lflag)) || 19789a4d6b1SPrafulla Wadaskar (params->lflag && (params->dflag || params->fflag))); 19889a4d6b1SPrafulla Wadaskar } 19989a4d6b1SPrafulla Wadaskar 20089a4d6b1SPrafulla Wadaskar static struct image_type_params fitimage_params = { 20189a4d6b1SPrafulla Wadaskar .name = "FIT Image support", 20289a4d6b1SPrafulla Wadaskar .header_size = sizeof(image_header_t), 20389a4d6b1SPrafulla Wadaskar .hdr = (void*)&header, 20489a4d6b1SPrafulla Wadaskar .verify_header = fit_verify_header, 20589a4d6b1SPrafulla Wadaskar .print_header = fit_print_contents, 20689a4d6b1SPrafulla Wadaskar .check_image_type = fit_check_image_types, 20789a4d6b1SPrafulla Wadaskar .fflag_handle = fit_handle_file, 2088e1c8966SPeter Tyser .set_header = NULL, /* FIT images use DTB header */ 20989a4d6b1SPrafulla Wadaskar .check_params = fit_check_params, 21089a4d6b1SPrafulla Wadaskar }; 21189a4d6b1SPrafulla Wadaskar 21289a4d6b1SPrafulla Wadaskar void init_fit_image_type (void) 21389a4d6b1SPrafulla Wadaskar { 21489a4d6b1SPrafulla Wadaskar mkimage_register (&fitimage_params); 21589a4d6b1SPrafulla Wadaskar } 216