diff --git a/tools/firmware-utils/src/imagetag.c b/tools/firmware-utils/src/imagetag.c index bebaba2f29..166ce9a0e2 100644 --- a/tools/firmware-utils/src/imagetag.c +++ b/tools/firmware-utils/src/imagetag.c @@ -231,6 +231,19 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \ fseek(binfile, rootfsoff + rootfslen - fwaddr + cfelen, SEEK_SET); fwrite(&deadcode, sizeof(uint32_t), 1, binfile); + oldrootfslen = rootfslen; + if (args->pad_given) { + uint32_t allfs = 0xffffffff; + uint32_t pad_size = args->pad_arg * 1024 * 1024; + + printf("Padding image to %d bytes ...\n", pad_size); + while (imagelen < pad_size) { + fwrite(&allfs, sizeof(uint32_t), 1, binfile); + imagelen += 4; + rootfslen += 4; + } + } + /* Flush the binfile buffer so that when we read from file, it contains * everything in the buffer */ @@ -260,6 +273,7 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \ rootfslen = oldrootfslen; rootfslen = ( (rootfslen % block_size) > 0 ? (((rootfslen / block_size) + 1) * block_size) : rootfslen ); kerneloffpadlen = rootfslen - oldrootfslen; + oldrootfslen = rootfslen; kerneloff = rootfsoff + rootfslen; kernellen = getlen(kernelfile); @@ -343,7 +357,7 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \ sprintf(tag.flashImageStart, "%lu", kerneloff); sprintf(tag.flashRootLength, "%lu", rootfslen + sizeof(deadcode)); } - int2tag(tag.rootLength, rootfslen + sizeof(deadcode)); + int2tag(tag.rootLength, oldrootfslen + sizeof(deadcode)); if (args->rsa_signature_given) { strncpy(tag.rsa_signature, args->rsa_signature_arg, RSASIG_LEN); @@ -483,6 +497,14 @@ int main(int argc, char **argv) exit(1); } } + + if (parsed_args.pad_given) { + if (parsed_args.pad_arg < 0) { + fprintf(stderr, "Error: pad size must be positive.\r"); + exit(1); + } + } + flash_start = strtoul(parsed_args.flash_start_arg, NULL, 16); image_offset = strtoul(parsed_args.image_offset_arg, NULL, 16); block_size = strtoul(parsed_args.block_size_arg, NULL, 16); diff --git a/tools/firmware-utils/src/imagetag.ggo b/tools/firmware-utils/src/imagetag.ggo index 7e8e7d90e3..7c9f943c6d 100644 --- a/tools/firmware-utils/src/imagetag.ggo +++ b/tools/firmware-utils/src/imagetag.ggo @@ -42,3 +42,4 @@ option "second-image-flag" - "Dual Image Flag (2=not-specified)." values="0", "1 option "inactive" - "Inactive Flag (2=not-specified)." values="0", "1", "2" default="2" typestr="flag-value" optional option "reserved2" - "String for second reserved section." string optional option "kernel-file-has-header" - "Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed" flag off +option "pad" p "Pad the image to this size if smaller (in MiB)" int typestr="size (in MiB)" optional diff --git a/tools/firmware-utils/src/imagetag_cmdline.c b/tools/firmware-utils/src/imagetag_cmdline.c index 91ac90b09d..efb82ac96b 100644 --- a/tools/firmware-utils/src/imagetag_cmdline.c +++ b/tools/firmware-utils/src/imagetag_cmdline.c @@ -58,12 +58,14 @@ const char *gengetopt_args_info_help[] = { " --inactive=flag-value Inactive Flag (2=not-specified). (possible \n values=\"0\", \"1\", \"2\" default=`2')", " --reserved2=STRING String for second reserved section.", " --kernel-file-has-header Indicates that the kernel file includes the \n kernel header with correct load address and \n entry point, so no changes are needed \n (default=off)", + " -p, --pad=size (in MiB) Pad the image to this size if smaller (in MiB)", 0 }; typedef enum {ARG_NO , ARG_FLAG , ARG_STRING + , ARG_INT } cmdline_parser_arg_type; static @@ -113,6 +115,7 @@ void clear_given (struct gengetopt_args_info *args_info) args_info->inactive_given = 0 ; args_info->reserved2_given = 0 ; args_info->kernel_file_has_header_given = 0 ; + args_info->pad_given = 0 ; } static @@ -165,6 +168,7 @@ void clear_args (struct gengetopt_args_info *args_info) args_info->reserved2_arg = NULL; args_info->reserved2_orig = NULL; args_info->kernel_file_has_header_flag = 0; + args_info->pad_orig = NULL; } @@ -199,6 +203,7 @@ void init_args_info(struct gengetopt_args_info *args_info) args_info->inactive_help = gengetopt_args_info_help[23] ; args_info->reserved2_help = gengetopt_args_info_help[24] ; args_info->kernel_file_has_header_help = gengetopt_args_info_help[25] ; + args_info->pad_help = gengetopt_args_info_help[26] ; } @@ -323,6 +328,7 @@ cmdline_parser_release (struct gengetopt_args_info *args_info) free_string_field (&(args_info->inactive_orig)); free_string_field (&(args_info->reserved2_arg)); free_string_field (&(args_info->reserved2_orig)); + free_string_field (&(args_info->pad_orig)); @@ -446,6 +452,8 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) write_into_file(outfile, "reserved2", args_info->reserved2_orig, 0); if (args_info->kernel_file_has_header_given) write_into_file(outfile, "kernel-file-has-header", 0, 0 ); + if (args_info->pad_given) + write_into_file(outfile, "pad", args_info->pad_orig, 0); i = EXIT_SUCCESS; @@ -690,6 +698,9 @@ int update_arg(void *field, char **orig_field, case ARG_FLAG: *((int *)field) = !*((int *)field); break; + case ARG_INT: + if (val) *((int *)field) = strtol (val, &stop_char, 0); + break; case ARG_STRING: if (val) { string_field = (char **)field; @@ -702,6 +713,17 @@ int update_arg(void *field, char **orig_field, break; }; + /* check numeric conversion */ + switch(arg_type) { + case ARG_INT: + if (val && !(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val); + return 1; /* failure */ + } + break; + default: + ; + }; /* store the original value */ switch(arg_type) { @@ -787,10 +809,11 @@ cmdline_parser_internal ( { "inactive", 1, NULL, 0 }, { "reserved2", 1, NULL, 0 }, { "kernel-file-has-header", 0, NULL, 0 }, + { "pad", 1, NULL, 'p' }, { 0, 0, 0, 0 } }; - c = getopt_long (argc, argv, "hVi:f:o:b:c:s:n:v:a:m:k:l:e:y:1:2:r:", long_options, &option_index); + c = getopt_long (argc, argv, "hVi:f:o:b:c:s:n:v:a:m:k:l:e:y:1:2:r:p:", long_options, &option_index); if (c == -1) break; /* Exit from `while (1)' loop. */ @@ -1010,6 +1033,18 @@ cmdline_parser_internal ( goto failure; break; + case 'p': /* Pad the image to this size if smaller (in MiB). */ + + + if (update_arg( (void *)&(args_info->pad_arg), + &(args_info->pad_orig), &(args_info->pad_given), + &(local_args_info.pad_given), optarg, 0, 0, ARG_INT, + check_ambiguity, override, 0, 0, + "pad", 'p', + additional_error)) + goto failure; + + break; case 0: /* Long option with no short option */ /* File with CFE to include in the image.. */ diff --git a/tools/firmware-utils/src/imagetag_cmdline.h b/tools/firmware-utils/src/imagetag_cmdline.h index c566a9f293..a6fd3896b7 100644 --- a/tools/firmware-utils/src/imagetag_cmdline.h +++ b/tools/firmware-utils/src/imagetag_cmdline.h @@ -109,6 +109,9 @@ struct gengetopt_args_info const char *reserved2_help; /**< @brief String for second reserved section. help description. */ int kernel_file_has_header_flag; /**< @brief Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed (default=off). */ const char *kernel_file_has_header_help; /**< @brief Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed help description. */ + int pad_arg; /**< @brief Pad the image to this size if smaller (in MiB). */ + char * pad_orig; /**< @brief Pad the image to this size if smaller (in MiB) original value given at command line. */ + const char *pad_help; /**< @brief Pad the image to this size if smaller (in MiB) help description. */ unsigned int help_given ; /**< @brief Whether help was given. */ unsigned int version_given ; /**< @brief Whether version was given. */ @@ -136,6 +139,7 @@ struct gengetopt_args_info unsigned int inactive_given ; /**< @brief Whether inactive was given. */ unsigned int reserved2_given ; /**< @brief Whether reserved2 was given. */ unsigned int kernel_file_has_header_given ; /**< @brief Whether kernel-file-has-header was given. */ + unsigned int pad_given ; /**< @brief Whether pad was given. */ } ;