@ -18,6 +18,8 @@
# include "fit_common.h"
# include "mkimage.h"
# include <image.h>
# include <stdarg.h>
# include <version.h>
# include <u-boot/crc.h>
static image_header_t header ;
@ -71,6 +73,207 @@ err_keydest:
}
/**
* fit_calc_size ( ) - Calculate the approximate size of the FIT we will generate
*/
static int fit_calc_size ( struct image_tool_params * params )
{
int size , total_size ;
size = imagetool_get_filesize ( params , params - > datafile ) ;
if ( size < 0 )
return - 1 ;
total_size = size ;
/* TODO(sjg@chromium.org): Add in the size of any other files */
/* Add plenty of space for headers, properties, nodes, etc. */
total_size + = 4096 ;
return total_size ;
}
static int fdt_property_file ( struct image_tool_params * params ,
void * fdt , const char * name , const char * fname )
{
struct stat sbuf ;
void * ptr ;
int ret ;
int fd ;
fd = open ( fname , O_RDWR | O_BINARY ) ;
if ( fd < 0 ) {
fprintf ( stderr , " %s: Can't open %s: %s \n " ,
params - > cmdname , fname , strerror ( errno ) ) ;
return - 1 ;
}
if ( fstat ( fd , & sbuf ) < 0 ) {
fprintf ( stderr , " %s: Can't stat %s: %s \n " ,
params - > cmdname , fname , strerror ( errno ) ) ;
goto err ;
}
ret = fdt_property_placeholder ( fdt , " data " , sbuf . st_size , & ptr ) ;
if ( ret )
return ret ;
ret = read ( fd , ptr , sbuf . st_size ) ;
if ( ret ! = sbuf . st_size ) {
fprintf ( stderr , " %s: Can't read %s: %s \n " ,
params - > cmdname , fname , strerror ( errno ) ) ;
goto err ;
}
return 0 ;
err :
close ( fd ) ;
return - 1 ;
}
static int fdt_property_strf ( void * fdt , const char * name , const char * fmt , . . . )
{
char str [ 100 ] ;
va_list ptr ;
va_start ( ptr , fmt ) ;
vsnprintf ( str , sizeof ( str ) , fmt , ptr ) ;
va_end ( ptr ) ;
return fdt_property_string ( fdt , name , str ) ;
}
/**
* fit_write_images ( ) - Write out a list of images to the FIT
*
* Include the main image ( params - > datafile ) .
*/
static int fit_write_images ( struct image_tool_params * params , char * fdt )
{
const char * typename ;
char str [ 100 ] ;
int ret ;
fdt_begin_node ( fdt , " images " ) ;
/* First the main image */
typename = genimg_get_type_short_name ( params - > fit_image_type ) ;
snprintf ( str , sizeof ( str ) , " %s@1 " , typename ) ;
fdt_begin_node ( fdt , str ) ;
fdt_property_string ( fdt , " description " , params - > imagename ) ;
fdt_property_string ( fdt , " type " , typename ) ;
fdt_property_string ( fdt , " arch " , genimg_get_arch_name ( params - > arch ) ) ;
fdt_property_string ( fdt , " os " , genimg_get_os_short_name ( params - > os ) ) ;
fdt_property_string ( fdt , " compression " ,
genimg_get_comp_short_name ( params - > comp ) ) ;
fdt_property_u32 ( fdt , " load " , params - > addr ) ;
fdt_property_u32 ( fdt , " entry " , params - > ep ) ;
/*
* Put data last since it is large . SPL may only load the first part
* of the DT , so this way it can access all the above fields .
*/
ret = fdt_property_file ( params , fdt , " data " , params - > datafile ) ;
if ( ret )
return ret ;
fdt_end_node ( fdt ) ;
fdt_end_node ( fdt ) ;
return 0 ;
}
/**
* fit_write_configs ( ) - Write out a list of configurations to the FIT
*
* Create a configuration with the main image in it .
*/
static void fit_write_configs ( struct image_tool_params * params , char * fdt )
{
const char * typename ;
char str [ 100 ] ;
fdt_begin_node ( fdt , " configurations " ) ;
fdt_property_string ( fdt , " default " , " conf@1 " ) ;
fdt_begin_node ( fdt , " conf@1 " ) ;
typename = genimg_get_type_short_name ( params - > fit_image_type ) ;
snprintf ( str , sizeof ( str ) , " %s@1 " , typename ) ;
fdt_property_string ( fdt , typename , str ) ;
fdt_end_node ( fdt ) ;
fdt_end_node ( fdt ) ;
}
static int fit_build_fdt ( struct image_tool_params * params , char * fdt , int size )
{
int ret ;
ret = fdt_create ( fdt , size ) ;
if ( ret )
return ret ;
fdt_finish_reservemap ( fdt ) ;
fdt_begin_node ( fdt , " " ) ;
fdt_property_strf ( fdt , " description " ,
" %s image with one or more FDT blobs " ,
genimg_get_type_name ( params - > fit_image_type ) ) ;
fdt_property_strf ( fdt , " creator " , " U-Boot mkimage %s " , PLAIN_VERSION ) ;
fdt_property_u32 ( fdt , " #address-cells " , 1 ) ;
ret = fit_write_images ( params , fdt ) ;
if ( ret )
return ret ;
fit_write_configs ( params , fdt ) ;
fdt_end_node ( fdt ) ;
ret = fdt_finish ( fdt ) ;
if ( ret )
return ret ;
return fdt_totalsize ( fdt ) ;
}
static int fit_build ( struct image_tool_params * params , const char * fname )
{
char * buf ;
int size ;
int ret ;
int fd ;
size = fit_calc_size ( params ) ;
if ( size < 0 )
return - 1 ;
buf = malloc ( size ) ;
if ( ! buf ) {
fprintf ( stderr , " %s: Out of memory (%d bytes) \n " ,
params - > cmdname , size ) ;
return - 1 ;
}
ret = fit_build_fdt ( params , buf , size ) ;
if ( ret < 0 ) {
fprintf ( stderr , " %s: Failed to build FIT image \n " ,
params - > cmdname ) ;
goto err ;
}
size = ret ;
fd = open ( fname , O_RDWR | O_CREAT | O_TRUNC | O_BINARY , 0666 ) ;
if ( fd < 0 ) {
fprintf ( stderr , " %s: Can't open %s: %s \n " ,
params - > cmdname , fname , strerror ( errno ) ) ;
goto err ;
}
ret = write ( fd , buf , size ) ;
if ( ret ! = size ) {
fprintf ( stderr , " %s: Can't write %s: %s \n " ,
params - > cmdname , fname , strerror ( errno ) ) ;
close ( fd ) ;
goto err ;
}
close ( fd ) ;
return 0 ;
err :
free ( buf ) ;
return - 1 ;
}
/**
* fit_handle_file - main FIT file processing function
*
* fit_handle_file ( ) runs dtc to convert . its to . itb , includes
@ -103,7 +306,14 @@ static int fit_handle_file(struct image_tool_params *params)
sprintf ( tmpfile , " %s%s " , params - > imagefile , MKIMAGE_TMPFILE_SUFFIX ) ;
/* We either compile the source file, or use the existing FIT image */
if ( params - > datafile ) {
if ( params - > auto_its ) {
if ( fit_build ( params , tmpfile ) ) {
fprintf ( stderr , " %s: failed to build FIT \n " ,
params - > cmdname ) ;
return EXIT_FAILURE ;
}
* cmd = ' \0 ' ;
} else if ( params - > datafile ) {
/* dtc -I dts -O dtb -p 500 datafile > tmpfile */
snprintf ( cmd , sizeof ( cmd ) , " %s %s %s > %s " ,
MKIMAGE_DTC , params - > dtc , params - > datafile , tmpfile ) ;
@ -112,7 +322,7 @@ static int fit_handle_file(struct image_tool_params *params)
snprintf ( cmd , sizeof ( cmd ) , " cp %s %s " ,
params - > imagefile , tmpfile ) ;
}
if ( system ( cmd ) = = - 1 ) {
if ( * cmd & & system ( cmd ) = = - 1 ) {
fprintf ( stderr , " %s: system(%s) failed: %s \n " ,
params - > cmdname , cmd , strerror ( errno ) ) ;
goto err_system ;
@ -248,6 +458,8 @@ static int fit_extract_contents(void *ptr, struct image_tool_params *params)
static int fit_check_params ( struct image_tool_params * params )
{
if ( params - > auto_its )
return 0 ;
return ( ( params - > dflag & & ( params - > fflag | | params - > lflag ) ) | |
( params - > fflag & & ( params - > dflag | | params - > lflag ) ) | |
( params - > lflag & & ( params - > dflag | | params - > fflag ) ) ) ;