tools: imagetag: add parameter for padding images
authorJonas Gorski <jogo@openwrt.org>
Sun, 27 May 2012 13:22:19 +0000 (13:22 +0000)
committerJonas Gorski <jogo@openwrt.org>
Sun, 27 May 2012 13:22:19 +0000 (13:22 +0000)
Allow images to be padded to a certain size. This prevents CFE from
flashing them to the second image offset.

SVN-Revision: 31875

tools/firmware-utils/src/imagetag.c
tools/firmware-utils/src/imagetag.ggo
tools/firmware-utils/src/imagetag_cmdline.c
tools/firmware-utils/src/imagetag_cmdline.h

index bebaba2f29dee03abbd9c89f2cc9cc50476ae48d..166ce9a0e2401a50469860f9993d42a199202ff2 100644 (file)
@@ -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);
index 7e8e7d90e32097a435edd260d6ea98fccc03ee12..7c9f943c6d2b3250faf11be4eaf50d87c63521d2 100644 (file)
@@ -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
index 91ac90b09d0b45aa13bd6ba2a17df016fbfa0b7e..efb82ac96b1bae6b1cc51548b27064fb6a16e3f6 100644 (file)
@@ -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..  */
index c566a9f293268724f40e39947e8c4f1b56fcb308..a6fd3896b705f277d1e59e71236f37d12bf77cf0 100644 (file)
@@ -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.  */
 
 } ;