*/
#include "mkimage.h"
+#include "imximage.h"
#include <image.h>
#include <version.h>
.imagename2 = "",
};
-static int h_compare_image_name(const void *vtype1, const void *vtype2)
+static enum ih_category cur_category;
+
+static int h_compare_category_name(const void *vtype1, const void *vtype2)
{
const int *type1 = vtype1;
const int *type2 = vtype2;
- const char *name1 = genimg_get_type_short_name(*type1);
- const char *name2 = genimg_get_type_short_name(*type2);
+ const char *name1 = genimg_get_cat_short_name(cur_category, *type1);
+ const char *name2 = genimg_get_cat_short_name(cur_category, *type2);
return strcmp(name1, name2);
}
-/* Show all image types supported by mkimage */
-static void show_image_types(void)
+static int show_valid_options(enum ih_category category)
{
- struct image_type_params *tparams;
- int order[IH_TYPE_COUNT];
+ int *order;
int count;
- int type;
+ int item;
int i;
+ count = genimg_get_cat_count(category);
+ order = calloc(count, sizeof(*order));
+ if (!order)
+ return -ENOMEM;
+
/* Sort the names in order of short name for easier reading */
- memset(order, '\0', sizeof(order));
- for (count = 0, type = 0; type < IH_TYPE_COUNT; type++) {
- tparams = imagetool_get_type(type);
- if (tparams)
- order[count++] = type;
- }
- qsort(order, count, sizeof(int), h_compare_image_name);
+ for (item = 0; item < count; item++)
+ order[item] = item;
+ cur_category = category;
+ qsort(order, count, sizeof(int), h_compare_category_name);
- fprintf(stderr, "\nInvalid image type. Supported image types:\n");
+ fprintf(stderr, "\nInvalid %s, supported are:\n",
+ genimg_get_cat_desc(category));
for (i = 0; i < count; i++) {
- type = order[i];
- tparams = imagetool_get_type(type);
- if (tparams) {
- fprintf(stderr, "\t%-15s %s\n",
- genimg_get_type_short_name(type),
- genimg_get_type_name(type));
- }
+ item = order[i];
+ fprintf(stderr, "\t%-15s %s\n",
+ genimg_get_cat_short_name(category, item),
+ genimg_get_cat_name(category, item));
}
fprintf(stderr, "\n");
+ free(order);
+
+ return 0;
}
static void usage(const char *msg)
" -x ==> set XIP (execute in place)\n",
params.cmdname);
fprintf(stderr,
- " %s [-D dtc_options] [-f fit-image.its|-f auto|-F] [-b <dtb> [-b <dtb>]] fit-image\n"
- " <dtb> file is used with -f auto, it may occour multiple times.\n",
+ " %s [-D dtc_options] [-f fit-image.its|-f auto|-F] [-b <dtb> [-b <dtb>]] [-i <ramdisk.cpio.gz>] fit-image\n"
+ " <dtb> file is used with -f auto, it may occur multiple times.\n",
params.cmdname);
fprintf(stderr,
" -D => set all options for device tree compiler\n"
- " -f => input filename for FIT source\n");
+ " -f => input filename for FIT source\n"
+ " -i => input filename for ramdisk file\n");
#ifdef CONFIG_FIT_SIGNATURE
fprintf(stderr,
- "Signing / verified boot options: [-k keydir] [-K dtb] [ -c <comment>] [-r]\n"
+ "Signing / verified boot options: [-E] [-k keydir] [-K dtb] [ -c <comment>] [-p addr] [-r] [-N engine]\n"
+ " -E => place data outside of the FIT structure\n"
" -k => set directory containing private keys\n"
" -K => write public keys to this .dtb file\n"
" -c => add comment in signature node\n"
" -F => re-sign existing FIT image\n"
- " -r => mark keys used as 'required' in dtb\n");
+ " -p => place external data at a static position\n"
+ " -r => mark keys used as 'required' in dtb\n"
+ " -N => engine to use for signing (pkcs11)\n");
#else
fprintf(stderr,
"Signing / verified boot not supported (CONFIG_FIT_SIGNATURE undefined)\n");
#endif
fprintf(stderr, " %s -V ==> print version information and exit\n",
params.cmdname);
- fprintf(stderr, "Use -T to see a list of available image types\n");
+ fprintf(stderr, "Use '-T list' to see a list of available image types\n");
exit(EXIT_FAILURE);
}
int opt;
while ((opt = getopt(argc, argv,
- "a:A:b:cC:d:D:e:Ef:Fk:K:ln:O:rR:qsT:vVx")) != -1) {
+ "a:A:b:c:C:d:D:e:Ef:Fk:i:K:ln:N:p:O:rR:qsT:vVx")) != -1) {
switch (opt) {
case 'a':
params.addr = strtoull(optarg, &ptr, 16);
break;
case 'A':
params.arch = genimg_get_arch_id(optarg);
- if (params.arch < 0)
+ if (params.arch < 0) {
+ show_valid_options(IH_ARCH);
usage("Invalid architecture");
+ }
break;
case 'b':
if (add_content(IH_TYPE_FLATDT, optarg)) {
break;
case 'C':
params.comp = genimg_get_comp_id(optarg);
- if (params.comp < 0)
+ if (params.comp < 0) {
+ show_valid_options(IH_COMP);
usage("Invalid compression type");
+ }
break;
case 'd':
params.datafile = optarg;
* The flattened image tree (FIT) format
* requires a flattened device tree image type
*/
- params.fit_image_type = params.type;
params.type = IH_TYPE_FLATDT;
params.fflag = 1;
break;
+ case 'i':
+ params.fit_ramdisk = optarg;
+ break;
case 'k':
params.keydir = optarg;
break;
case 'n':
params.imagename = optarg;
break;
+ case 'N':
+ params.engine_id = optarg;
+ break;
case 'O':
params.os = genimg_get_os_id(optarg);
- if (params.os < 0)
+ if (params.os < 0) {
+ show_valid_options(IH_OS);
usage("Invalid operating system");
+ }
+ break;
+ case 'p':
+ params.external_offset = strtoull(optarg, &ptr, 16);
+ if (*ptr) {
+ fprintf(stderr, "%s: invalid offset size %s\n",
+ params.cmdname, optarg);
+ exit(EXIT_FAILURE);
+ }
break;
case 'q':
params.quiet = 1;
params.skipcpy = 1;
break;
case 'T':
+ if (strcmp(optarg, "list") == 0) {
+ show_valid_options(IH_TYPE);
+ exit(EXIT_SUCCESS);
+ }
type = genimg_get_type_id(optarg);
if (type < 0) {
- show_image_types();
+ show_valid_options(IH_TYPE);
usage("Invalid image type");
}
break;
* will always be IH_TYPE_FLATDT in this case).
*/
if (params.type == IH_TYPE_FLATDT) {
- params.fit_image_type = type;
+ params.fit_image_type = type ? type : IH_TYPE_KERNEL;
+ /* For auto_its, datafile is always 'auto' */
if (!params.auto_its)
params.datafile = datafile;
+ else if (!params.datafile)
+ usage("Missing data file for auto-FIT (use -d)");
} else if (type != IH_TYPE_INVALID) {
+ if (type == IH_TYPE_SCRIPT && !params.datafile)
+ usage("Missing data file for script (use -d)");
params.type = type;
}
usage("Missing output filename");
}
-
int main(int argc, char **argv)
{
int ifd = -1;
} else {
copy_file(ifd, params.datafile, pad_len);
}
+ if (params.type == IH_TYPE_FIRMWARE_IVT) {
+ /* Add alignment and IVT */
+ uint32_t aligned_filesize = (params.file_size + 0x1000
+ - 1) & ~(0x1000 - 1);
+ flash_header_v2_t ivt_header = { { 0xd1, 0x2000, 0x40 },
+ params.addr, 0, 0, 0, params.addr
+ + aligned_filesize
+ - tparams->header_size,
+ params.addr + aligned_filesize
+ - tparams->header_size
+ + 0x20, 0 };
+ int i = params.file_size;
+ for (; i < aligned_filesize; i++) {
+ if (write(ifd, (char *) &i, 1) != 1) {
+ fprintf(stderr,
+ "%s: Write error on %s: %s\n",
+ params.cmdname,
+ params.imagefile,
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ }
+ if (write(ifd, &ivt_header, sizeof(flash_header_v2_t))
+ != sizeof(flash_header_v2_t)) {
+ fprintf(stderr, "%s: Write error on %s: %s\n",
+ params.cmdname,
+ params.imagefile,
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ }
}
/* We're a bit of paranoid */
if (tparams->print_header)
tparams->print_header (ptr);
else {
- fprintf (stderr, "%s: Can't print header for %s: %s\n",
- params.cmdname, tparams->name, strerror(errno));
- exit (EXIT_FAILURE);
+ fprintf (stderr, "%s: Can't print header for %s\n",
+ params.cmdname, tparams->name);
}
(void) munmap((void *)ptr, sbuf.st_size);