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 50*aa6d6db4SSimon Glass int mmap_fdt(struct mkimage_params *params, const char *fname, void **blobp, 51*aa6d6db4SSimon Glass struct stat *sbuf) 52*aa6d6db4SSimon Glass { 53*aa6d6db4SSimon Glass void *ptr; 54*aa6d6db4SSimon Glass int fd; 55*aa6d6db4SSimon Glass 56*aa6d6db4SSimon Glass /* Load FIT blob into memory (we need to write hashes/signatures) */ 57*aa6d6db4SSimon Glass fd = open(fname, O_RDWR | O_BINARY); 58*aa6d6db4SSimon Glass 59*aa6d6db4SSimon Glass if (fd < 0) { 60*aa6d6db4SSimon Glass fprintf(stderr, "%s: Can't open %s: %s\n", 61*aa6d6db4SSimon Glass params->cmdname, fname, strerror(errno)); 62*aa6d6db4SSimon Glass unlink(fname); 63*aa6d6db4SSimon Glass return -1; 64*aa6d6db4SSimon Glass } 65*aa6d6db4SSimon Glass 66*aa6d6db4SSimon Glass if (fstat(fd, sbuf) < 0) { 67*aa6d6db4SSimon Glass fprintf(stderr, "%s: Can't stat %s: %s\n", 68*aa6d6db4SSimon Glass params->cmdname, fname, strerror(errno)); 69*aa6d6db4SSimon Glass unlink(fname); 70*aa6d6db4SSimon Glass return -1; 71*aa6d6db4SSimon Glass } 72*aa6d6db4SSimon Glass 73*aa6d6db4SSimon Glass ptr = mmap(0, sbuf->st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 74*aa6d6db4SSimon Glass if (ptr == MAP_FAILED) { 75*aa6d6db4SSimon Glass fprintf(stderr, "%s: Can't read %s: %s\n", 76*aa6d6db4SSimon Glass params->cmdname, fname, strerror(errno)); 77*aa6d6db4SSimon Glass unlink(fname); 78*aa6d6db4SSimon Glass return -1; 79*aa6d6db4SSimon Glass } 80*aa6d6db4SSimon Glass 81*aa6d6db4SSimon Glass /* check if ptr has a valid blob */ 82*aa6d6db4SSimon Glass if (fdt_check_header(ptr)) { 83*aa6d6db4SSimon Glass fprintf(stderr, "%s: Invalid FIT blob\n", params->cmdname); 84*aa6d6db4SSimon Glass unlink(fname); 85*aa6d6db4SSimon Glass return -1; 86*aa6d6db4SSimon Glass } 87*aa6d6db4SSimon Glass 88*aa6d6db4SSimon Glass *blobp = ptr; 89*aa6d6db4SSimon Glass return fd; 90*aa6d6db4SSimon Glass } 91*aa6d6db4SSimon 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]; 10889a4d6b1SPrafulla Wadaskar int tfd; 10989a4d6b1SPrafulla Wadaskar struct stat sbuf; 110*aa6d6db4SSimon Glass void *ptr; 11189a4d6b1SPrafulla Wadaskar 11289a4d6b1SPrafulla Wadaskar /* Flattened Image Tree (FIT) format handling */ 11389a4d6b1SPrafulla Wadaskar debug ("FIT format handling\n"); 11489a4d6b1SPrafulla Wadaskar 11589a4d6b1SPrafulla Wadaskar /* call dtc to include binary properties into the tmp file */ 11689a4d6b1SPrafulla Wadaskar if (strlen (params->imagefile) + 11789a4d6b1SPrafulla Wadaskar strlen (MKIMAGE_TMPFILE_SUFFIX) + 1 > sizeof (tmpfile)) { 11889a4d6b1SPrafulla Wadaskar fprintf (stderr, "%s: Image file name (%s) too long, " 11989a4d6b1SPrafulla Wadaskar "can't create tmpfile", 12089a4d6b1SPrafulla Wadaskar params->imagefile, params->cmdname); 12189a4d6b1SPrafulla Wadaskar return (EXIT_FAILURE); 12289a4d6b1SPrafulla Wadaskar } 12389a4d6b1SPrafulla Wadaskar sprintf (tmpfile, "%s%s", params->imagefile, MKIMAGE_TMPFILE_SUFFIX); 12489a4d6b1SPrafulla Wadaskar 125ee7c0fc7SLars Rasmusson /* dtc -I dts -O dtb -p 500 datafile > tmpfile */ 12689a4d6b1SPrafulla Wadaskar sprintf (cmd, "%s %s %s > %s", 12789a4d6b1SPrafulla Wadaskar MKIMAGE_DTC, params->dtc, params->datafile, tmpfile); 12889a4d6b1SPrafulla Wadaskar debug ("Trying to execute \"%s\"\n", cmd); 12989a4d6b1SPrafulla Wadaskar if (system (cmd) == -1) { 13089a4d6b1SPrafulla Wadaskar fprintf (stderr, "%s: system(%s) failed: %s\n", 13189a4d6b1SPrafulla Wadaskar params->cmdname, cmd, strerror(errno)); 132*aa6d6db4SSimon Glass goto err_system; 13389a4d6b1SPrafulla Wadaskar } 13489a4d6b1SPrafulla Wadaskar 135*aa6d6db4SSimon Glass tfd = mmap_fdt(params, tmpfile, &ptr, &sbuf); 136*aa6d6db4SSimon Glass if (tfd < 0) 137*aa6d6db4SSimon Glass goto err_mmap; 13889a4d6b1SPrafulla Wadaskar 13989a4d6b1SPrafulla Wadaskar /* set hashes for images in the blob */ 140bbb467dcSSimon Glass if (fit_add_verification_data(ptr)) { 14189a4d6b1SPrafulla Wadaskar fprintf (stderr, "%s Can't add hashes to FIT blob", 14289a4d6b1SPrafulla Wadaskar params->cmdname); 143*aa6d6db4SSimon Glass goto err_add_hashes; 14489a4d6b1SPrafulla Wadaskar } 14589a4d6b1SPrafulla Wadaskar 14689a4d6b1SPrafulla Wadaskar /* add a timestamp at offset 0 i.e., root */ 14789a4d6b1SPrafulla Wadaskar if (fit_set_timestamp (ptr, 0, sbuf.st_mtime)) { 14889a4d6b1SPrafulla Wadaskar fprintf (stderr, "%s: Can't add image timestamp\n", 14989a4d6b1SPrafulla Wadaskar params->cmdname); 150*aa6d6db4SSimon Glass goto err_add_timestamp; 15189a4d6b1SPrafulla Wadaskar } 15289a4d6b1SPrafulla Wadaskar debug ("Added timestamp successfully\n"); 15389a4d6b1SPrafulla Wadaskar 15489a4d6b1SPrafulla Wadaskar munmap ((void *)ptr, sbuf.st_size); 15589a4d6b1SPrafulla Wadaskar close (tfd); 15689a4d6b1SPrafulla Wadaskar 15789a4d6b1SPrafulla Wadaskar if (rename (tmpfile, params->imagefile) == -1) { 15889a4d6b1SPrafulla Wadaskar fprintf (stderr, "%s: Can't rename %s to %s: %s\n", 15989a4d6b1SPrafulla Wadaskar params->cmdname, tmpfile, params->imagefile, 16089a4d6b1SPrafulla Wadaskar strerror (errno)); 16189a4d6b1SPrafulla Wadaskar unlink (tmpfile); 16289a4d6b1SPrafulla Wadaskar unlink (params->imagefile); 16389a4d6b1SPrafulla Wadaskar return (EXIT_FAILURE); 16489a4d6b1SPrafulla Wadaskar } 16589a4d6b1SPrafulla Wadaskar return (EXIT_SUCCESS); 166*aa6d6db4SSimon Glass 167*aa6d6db4SSimon Glass err_add_timestamp: 168*aa6d6db4SSimon Glass err_add_hashes: 169*aa6d6db4SSimon Glass munmap(ptr, sbuf.st_size); 170*aa6d6db4SSimon Glass err_mmap: 171*aa6d6db4SSimon Glass err_system: 172*aa6d6db4SSimon Glass unlink(tmpfile); 173*aa6d6db4SSimon Glass return -1; 17489a4d6b1SPrafulla Wadaskar } 17589a4d6b1SPrafulla Wadaskar 17689a4d6b1SPrafulla Wadaskar static int fit_check_params (struct mkimage_params *params) 17789a4d6b1SPrafulla Wadaskar { 17889a4d6b1SPrafulla Wadaskar return ((params->dflag && (params->fflag || params->lflag)) || 17989a4d6b1SPrafulla Wadaskar (params->fflag && (params->dflag || params->lflag)) || 18089a4d6b1SPrafulla Wadaskar (params->lflag && (params->dflag || params->fflag))); 18189a4d6b1SPrafulla Wadaskar } 18289a4d6b1SPrafulla Wadaskar 18389a4d6b1SPrafulla Wadaskar static struct image_type_params fitimage_params = { 18489a4d6b1SPrafulla Wadaskar .name = "FIT Image support", 18589a4d6b1SPrafulla Wadaskar .header_size = sizeof(image_header_t), 18689a4d6b1SPrafulla Wadaskar .hdr = (void*)&header, 18789a4d6b1SPrafulla Wadaskar .verify_header = fit_verify_header, 18889a4d6b1SPrafulla Wadaskar .print_header = fit_print_contents, 18989a4d6b1SPrafulla Wadaskar .check_image_type = fit_check_image_types, 19089a4d6b1SPrafulla Wadaskar .fflag_handle = fit_handle_file, 1918e1c8966SPeter Tyser .set_header = NULL, /* FIT images use DTB header */ 19289a4d6b1SPrafulla Wadaskar .check_params = fit_check_params, 19389a4d6b1SPrafulla Wadaskar }; 19489a4d6b1SPrafulla Wadaskar 19589a4d6b1SPrafulla Wadaskar void init_fit_image_type (void) 19689a4d6b1SPrafulla Wadaskar { 19789a4d6b1SPrafulla Wadaskar mkimage_register (&fitimage_params); 19889a4d6b1SPrafulla Wadaskar } 199