summaryrefslogtreecommitdiffstats
path: root/commands
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2011-12-17 16:33:57 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2011-12-17 16:33:57 +0100
commit146a7fe4a2427d4aaece1d1a642c52a50c95691f (patch)
tree610db5431aeffbda14d1f37381995a7322ce21aa /commands
parent84fd8a956cda82b54c85d8047c6f7ed7ec6879c5 (diff)
parent52fac4b1ff5da3deff3e9f0cae681ff23337c1f1 (diff)
downloadbarebox-146a7fe4a2427d4aaece1d1a642c52a50c95691f.tar.gz
barebox-146a7fe4a2427d4aaece1d1a642c52a50c95691f.tar.xz
Merge branch 'work/uimage' into next
Conflicts: arch/ppc/lib/ppclinux.c commands/bootm.c include/boot.h Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'commands')
-rw-r--r--commands/Kconfig35
-rw-r--r--commands/Makefile2
-rw-r--r--commands/bootm.c451
-rw-r--r--commands/iminfo.c71
-rw-r--r--commands/uimage.c108
5 files changed, 467 insertions, 200 deletions
diff --git a/commands/Kconfig b/commands/Kconfig
index ebc9c7f2d0..3e9f06fce5 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -310,11 +310,40 @@ config CMD_BOOTM_SHOW_TYPE
depends on CMD_BOOTM
prompt "show image information"
-config CMD_IMINFO
+config CMD_BOOTM_VERBOSE
bool
- prompt "iminfo"
+ prompt "bootm verbose support"
+ depends on CMD_BOOTM
+ help
+ support verbose bootm (-v switch)
+
+config CMD_BOOTM_INITRD
+ bool
+ prompt "bootm initrd support"
+ depends on CMD_BOOTM
+ help
+ support initrds in bootm
+
+config CMD_BOOTM_OFTREE
+ bool
+ select OFTREE
+ prompt "bootm oftree support"
+ help
+ say yes here to support passing a flat device tree to the kernel
+
+config CMD_BOOTM_OFTREE_UIMAGE
+ bool
+ prompt "support passing oftree uImages"
+ depends on CMD_BOOTM_OFTREE
+ help
+ Support using oftree uImages. Without this only raw oftree
+ blobs can be used.
+
+config CMD_UIMAGE
+ tristate
+ prompt "uimage"
help
- Show information about uImages
+ Show information about uImage and also extract and verify uImages.
config CMD_BOOTZ
tristate
diff --git a/commands/Makefile b/commands/Makefile
index aa013de107..24753be80d 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -1,5 +1,5 @@
obj-$(CONFIG_CMD_BOOTM) += bootm.o
-obj-$(CONFIG_CMD_IMINFO) += iminfo.o
+obj-$(CONFIG_CMD_UIMAGE) += uimage.o
obj-$(CONFIG_CMD_LINUX16) += linux16.o
obj-$(CONFIG_CMD_LOADB) += loadb.o xyzModem.o
obj-$(CONFIG_CMD_LOADY) += loadb.o xyzModem.o
diff --git a/commands/bootm.c b/commands/bootm.c
index f98a51c559..c23f4f3996 100644
--- a/commands/bootm.c
+++ b/commands/bootm.c
@@ -38,202 +38,410 @@
#include <errno.h>
#include <boot.h>
#include <of.h>
+#include <libfdt.h>
#include <rtc.h>
#include <init.h>
+#include <of.h>
#include <magicvar.h>
#include <uncompress.h>
+#include <memory.h>
+#include <filetype.h>
#include <asm-generic/memory_layout.h>
-struct image_handle_data* image_handle_data_get_by_num(struct image_handle* handle, int num)
+static LIST_HEAD(handler_list);
+
+#ifdef CONFIG_CMD_BOOTM_INITRD
+static inline int bootm_initrd(struct image_data *data)
+{
+ return data->initrd ? 1 : 0;
+}
+#else
+static inline int bootm_initrd(struct image_data *data)
{
- if (!handle || num < 0 || num >= handle->nb_data_entries)
- return NULL;
+ return 0;
+}
+#endif
- return &handle->data_entries[num];
+int register_image_handler(struct image_handler *handler)
+{
+ list_add_tail(&handler->list, &handler_list);
+ return 0;
}
-int relocate_image(struct image_handle *handle, void *load_address)
+#define UIMAGE_SOME_ADDRESS (UIMAGE_INVALID_ADDRESS - 1)
+
+static int bootm_open_os_uimage(struct image_data *data)
{
- image_header_t *hdr = &handle->header;
- unsigned long len = image_get_size(hdr);
- struct image_handle_data *iha;
- void *data;
int ret;
- iha = image_handle_data_get_by_num(handle, 0);
- data = iha->data;
+ data->os = uimage_open(data->os_file);
+ if (!data->os)
+ return -EINVAL;
- switch (image_get_comp(hdr)) {
- case IH_COMP_NONE:
- if (load_address == data) {
- printf (" XIP ... ");
- } else {
- memmove(load_address, data, len);
- }
- break;
- default:
- printf (" Uncompressing ... ");
- ret = uncompress(data, len, NULL, NULL, load_address, NULL,
- uncompress_err_stdout);
- if (ret)
+ if (data->verify) {
+ ret = uimage_verify(data->os);
+ if (ret) {
+ printf("Checking data crc failed with %s\n",
+ strerror(-ret));
return ret;
- break;
+ }
+ }
+
+ uimage_print_contents(data->os);
+
+ if (data->os->header.ih_arch != IH_ARCH) {
+ printf("Unsupported Architecture 0x%x\n",
+ data->os->header.ih_arch);
+ return -EINVAL;
+ }
+
+ if (data->os_address == UIMAGE_SOME_ADDRESS)
+ data->os_address = data->os->header.ih_load;
+
+ if (data->os_address != UIMAGE_INVALID_ADDRESS) {
+ data->os_res = uimage_load_to_sdram(data->os, 0,
+ data->os_address);
+ if (!data->os_res)
+ return -ENOMEM;
}
return 0;
}
-EXPORT_SYMBOL(relocate_image);
-
-static LIST_HEAD(handler_list);
-int register_image_handler(struct image_handler *handler)
+static int bootm_open_initrd_uimage(struct image_data *data)
{
- list_add_tail(&handler->list, &handler_list);
+ int ret;
+
+ if (!data->initrd_file)
+ return 0;
+
+ if (strcmp(data->os_file, data->initrd_file)) {
+ data->initrd = uimage_open(data->initrd_file);
+ if (!data->initrd)
+ return -EINVAL;
+
+ if (data->verify) {
+ ret = uimage_verify(data->initrd);
+ if (ret) {
+ printf("Checking data crc failed with %s\n",
+ strerror(-ret));
+ }
+ }
+ uimage_print_contents(data->initrd);
+ } else {
+ data->initrd = data->os;
+ }
+
+ if (data->initrd_address == UIMAGE_SOME_ADDRESS)
+ data->initrd_address = data->initrd->header.ih_load;
+
+ if (data->initrd_address != UIMAGE_INVALID_ADDRESS) {
+ data->initrd_res = uimage_load_to_sdram(data->initrd,
+ data->initrd_num,
+ data->initrd_address);
+ if (!data->initrd_res)
+ return -ENOMEM;
+ }
+
return 0;
}
-/*
- * generate a image_handle from a multi_image
- * this image_handle can be freed by unmap_image
- */
-static struct image_handle *get_fake_image_handle(struct image_data *data, int num)
+#ifdef CONFIG_OFTREE
+static int bootm_open_oftree(struct image_data *data, char *oftree, int num)
{
- struct image_handle *handle;
- struct image_handle_data* iha;
- image_header_t *header;
+ enum filetype ft;
+ struct fdt_header *fdt;
+ int ret;
+ size_t size;
+
+ ft = file_name_detect_type(oftree);
+ if ((int)ft < 0)
+ return ft;
+
+ if (ft == filetype_uimage) {
+#ifdef CONFIG_CMD_BOOTM_OFTREE_UIMAGE
+ struct uimage_handle *of_handle;
+ int release = 0;
+
+ if (!strcmp(data->os_file, oftree)) {
+ of_handle = data->os;
+ } else if (!strcmp(data->initrd_file, oftree)) {
+ of_handle = data->initrd;
+ } else {
+ of_handle = uimage_open(oftree);
+ if (!of_handle)
+ return -ENODEV;
+ uimage_print_contents(of_handle);
+ release = 1;
+ }
+
+ fdt = uimage_load_to_buf(of_handle, num, &size);
+
+ if (release)
+ uimage_close(of_handle);
+#else
+ return -EINVAL;
+#endif
+ } else {
+ fdt = read_file(oftree, &size);
+ if (!fdt) {
+ perror("open");
+ return -ENODEV;
+ }
+ }
+
+ ft = file_detect_type(fdt);
+ if (ft != filetype_oftree) {
+ printf("%s is not a oftree but %s\n", oftree,
+ file_type_to_string(ft));
+ }
+
+ if (bootm_verbose(data))
+ printf("Loading oftree from '%s'\n", oftree);
+
+ fdt = xrealloc(fdt, size + 0x8000);
+ fdt_open_into(fdt, fdt, size + 0x8000);
+
+ if (!fdt) {
+ printf("unable to read %s\n", oftree);
+ return -ENODEV;
+ }
+
+ ret = of_fix_tree(fdt);
+ if (ret)
+ return ret;
- iha = image_handle_data_get_by_num(data->os, num);
+ if (bootm_verbose(data) > 1)
+ fdt_print(fdt, "/");
- handle = xzalloc(sizeof(struct image_handle));
- header = &handle->header;
- handle->data_entries = gen_image_handle_data(iha->data, iha->len);
- handle->nb_data_entries = 1;
- header->ih_size = cpu_to_uimage(iha->len);
- handle->data = handle->data_entries[0].data;
+ data->oftree = fdt;
- return handle;
+ return ret;
+}
+#endif
+
+static struct image_handler *bootm_find_handler(enum filetype filetype,
+ struct image_data *data)
+{
+ struct image_handler *handler;
+
+ list_for_each_entry(handler, &handler_list, list) {
+ if (filetype != filetype_uimage &&
+ handler->filetype == filetype)
+ return handler;
+ if (filetype == filetype_uimage &&
+ handler->ih_os == data->os->header.ih_os)
+ return handler;
+ }
+
+ return NULL;
+}
+
+static void bootm_image_name_and_no(char *name, int *no)
+{
+ char *at;
+
+ *no = 0;
+
+ at = strchr(name, '@');
+ if (!at)
+ return;
+
+ *at++ = 0;
+
+ *no = simple_strtoul(at, NULL, 10);
}
static int do_bootm(struct command *cmdtp, int argc, char *argv[])
{
- int opt;
- image_header_t *os_header;
- struct image_handle *os_handle = NULL;
+ int opt;
struct image_handler *handler;
struct image_data data;
- const char *initrdname = NULL;
int ret = 1;
+ enum filetype os_type, initrd_type = filetype_unknown;
+ char *oftree = NULL;
+ int fallback = 0;
memset(&data, 0, sizeof(struct image_data));
- data.verify = 1;
- data.initrd_address = ~0;
- while ((opt = getopt(argc, argv, "nr:L:")) > 0) {
+ data.initrd_address = UIMAGE_SOME_ADDRESS;
+ data.os_address = UIMAGE_SOME_ADDRESS;
+ data.verify = 0;
+ data.verbose = 0;
+
+ while ((opt = getopt(argc, argv, "cL:r:a:e:vo:f")) > 0) {
switch(opt) {
- case 'n':
- data.verify = 0;
+ case 'c':
+ data.verify = 1;
break;
+#ifdef CONFIG_CMD_BOOTM_INITRD
case 'L':
data.initrd_address = simple_strtoul(optarg, NULL, 0);
break;
case 'r':
- initrdname = optarg;
+ data.initrd_file = optarg;
+ break;
+#endif
+ case 'a':
+ data.os_address = simple_strtoul(optarg, NULL, 0);
+ break;
+ case 'e':
+ data.os_entry = simple_strtoul(optarg, NULL, 0);
+ break;
+ case 'v':
+ data.verbose++;
+ break;
+ case 'o':
+ oftree = optarg;
+ break;
+ case 'f':
+ fallback = 1;
break;
default:
break;
}
}
-#ifdef CONFIG_OFTREE
- data.oftree = of_get_fixed_tree();
-#endif
+ if (optind == argc)
+ return COMMAND_ERROR_USAGE;
+
+ data.os_file = argv[optind];
- if (optind == argc) {
- ret = COMMAND_ERROR_USAGE;
+ bootm_image_name_and_no(data.os_file, &data.os_num);
+
+ os_type = file_name_detect_type(data.os_file);
+ if ((int)os_type < 0) {
+ printf("could not open %s: %s\n", data.os_file,
+ strerror(-os_type));
goto err_out;
}
- os_handle = map_image(argv[optind], data.verify);
- if (!os_handle)
+ if (!fallback && os_type == filetype_unknown) {
+ printf("Unknown OS filetype (try -f)\n");
goto err_out;
- data.os = os_handle;
-
- os_header = &os_handle->header;
+ }
- if (image_get_arch(os_header) != IH_ARCH) {
- printf("Unsupported Architecture 0x%x\n",
- image_get_arch(os_header));
- goto err_out;
+ if (os_type == filetype_uimage) {
+ ret = bootm_open_os_uimage(&data);
+ if (ret) {
+ printf("loading initrd failed with %s\n",
+ strerror(-ret));
+ goto err_out;
+ }
}
- if (initrdname) {
- /* check for multi image @<num> */
- if (initrdname[0] == '@') {
- int num = simple_strtol(optarg + 1, NULL, 0);
+ if (bootm_initrd(&data)) {
+ bootm_image_name_and_no(data.initrd_file, &data.initrd_num);
- data.initrd = get_fake_image_handle(&data, num);
- } else {
- data.initrd = map_image(optarg, data.verify);
- }
- if (!data.initrd)
+ initrd_type = file_name_detect_type(data.initrd_file);
+ if ((int)initrd_type < 0) {
+ printf("could not open %s: %s\n", data.initrd_file,
+ strerror(-initrd_type));
goto err_out;
+ }
+ if (initrd_type == filetype_uimage) {
+ ret = bootm_open_initrd_uimage(&data);
+ if (ret) {
+ printf("loading initrd failed with %s\n",
+ strerror(-ret));
+ goto err_out;
+ }
+ }
}
- /*
- * We have reached the point of no return: we are going to
- * overwrite all exception vector code, so we cannot easily
- * recover from any failures any more...
- */
-
- puts ("OK\n");
-
- /*
- * FIXME: we do not check at all whether
- * - we will write the image to sdram
- * - we overwrite ourselves
- * - kernel and initrd overlap
- */
- ret = relocate_image(data.os, (void *)image_get_load(os_header));
- if (ret)
- goto err_out;
+ if (bootm_verbose(&data)) {
+ printf("\nLoading OS %s '%s'", file_type_to_string(os_type),
+ data.os_file);
+ if (os_type == filetype_uimage &&
+ data.os->header.ih_type == IH_TYPE_MULTI)
+ printf(", multifile image %d", data.os_num);
+ printf("\n");
+ if (data.os_res)
+ printf("OS image is at 0x%08x-0x%08x\n",
+ data.os_res->start,
+ data.os_res->start +
+ data.os_res->size - 1);
+ else
+ printf("OS image not yet relocated\n");
+
+ if (data.initrd_file) {
+ printf("Loading initrd %s '%s'",
+ file_type_to_string(initrd_type),
+ data.initrd_file);
+ if (initrd_type == filetype_uimage &&
+ data.initrd->header.ih_type == IH_TYPE_MULTI)
+ printf(", multifile image %d", data.initrd_num);
+ printf("\n");
+ if (data.initrd_res)
+ printf("initrd is at 0x%08x-0x%08x\n",
+ data.initrd_res->start,
+ data.initrd_res->start +
+ data.initrd_res->size - 1);
+ else
+ printf("initrd image not yet relocated\n");
+ }
+ }
- if (data.initrd) {
- if (data.initrd && data.initrd_address == ~0)
- data.initrd_address = uimage_to_cpu(data.initrd->header.ih_load);
+#ifdef CONFIG_OFTREE
+ if (oftree) {
+ int oftree_num;
- data.initrd_size = image_get_data_size(&data.initrd->header);
+ bootm_image_name_and_no(oftree, &oftree_num);
- ret = relocate_image(data.initrd, (void *)data.initrd_address);
+ ret = bootm_open_oftree(&data, oftree, oftree_num);
if (ret)
goto err_out;
}
-
- /* loop through the registered handlers */
- list_for_each_entry(handler, &handler_list, list) {
- if (image_get_os(os_header) == handler->image_type) {
- handler->bootm(&data);
- printf("handler returned!\n");
- goto err_out;
- }
+#endif
+ if (data.os_address == UIMAGE_SOME_ADDRESS)
+ data.os_address = UIMAGE_INVALID_ADDRESS;
+ if (data.initrd_address == UIMAGE_SOME_ADDRESS)
+ data.initrd_address = UIMAGE_INVALID_ADDRESS;
+
+ handler = bootm_find_handler(os_type, &data);
+ if (!handler) {
+ printf("no image handler found for image type %s\n",
+ file_type_to_string(os_type));
+ if (os_type == filetype_uimage)
+ printf("and os type: %d\n", data.os->header.ih_os);
+ goto err_out;
}
- printf("no image handler found for image type %d\n",
- image_get_os(os_header));
+ if (bootm_verbose(&data))
+ printf("Passing control to %s handler\n", handler->name);
+
+ ret = handler->bootm(&data);
+
+ printf("handler failed with %s\n", strerror(-ret));
err_out:
- if (os_handle)
- unmap_image(os_handle);
- if (data.initrd)
- unmap_image(data.initrd);
- return ret;
+ if (data.os_res)
+ release_sdram_region(data.os_res);
+ if (data.initrd_res)
+ release_sdram_region(data.initrd_res);
+ if (data.initrd && data.initrd != data.os)
+ uimage_close(data.initrd);
+ if (data.os)
+ uimage_close(data.os);
+ return 1;
}
BAREBOX_CMD_HELP_START(bootm)
BAREBOX_CMD_HELP_USAGE("bootm [OPTIONS] image\n")
BAREBOX_CMD_HELP_SHORT("Boot an application image.\n")
-BAREBOX_CMD_HELP_OPT ("-n", "Do not verify the image (speeds up boot process)\n")
+BAREBOX_CMD_HELP_OPT ("-c", "crc check uImage data\n")
+#ifdef CONFIG_CMD_BOOTM_INITRD
BAREBOX_CMD_HELP_OPT ("-r <initrd>","specify an initrd image\n")
-BAREBOX_CMD_HELP_OPT ("-L <load addr>","specify initrd load address")
+BAREBOX_CMD_HELP_OPT ("-L <load addr>","specify initrd load address\n")
+#endif
+BAREBOX_CMD_HELP_OPT ("-a <load addr>","specify os load address\n")
+BAREBOX_CMD_HELP_OPT ("-e <ofs>","entry point to the image relative to start (0)\n")
+#ifdef CONFIG_OFTREE
+BAREBOX_CMD_HELP_OPT ("-o <oftree>","specify oftree\n")
+#endif
+#ifdef CONFIG_CMD_BOOTM_VERBOSE
+BAREBOX_CMD_HELP_OPT ("-v","verbose\n")
+#endif
BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(bootm)
@@ -244,13 +452,6 @@ BAREBOX_CMD_END
BAREBOX_MAGICVAR(bootargs, "Linux Kernel parameters");
-#ifdef CONFIG_BZLIB
-void bz_internal_error(int errcode)
-{
- printf ("BZIP2 internal error %d\n", errcode);
-}
-#endif /* CONFIG_BZLIB */
-
/**
* @file
* @brief Boot support for Linux
diff --git a/commands/iminfo.c b/commands/iminfo.c
deleted file mode 100644
index 2fde9bc09c..0000000000
--- a/commands/iminfo.c
+++ /dev/null
@@ -1,71 +0,0 @@
-#include <common.h>
-#include <command.h>
-#include <image.h>
-#include <fs.h>
-#include <malloc.h>
-#include <fcntl.h>
-#include <errno.h>
-
-static int image_info(image_header_t *hdr)
-{
- u32 len, checksum;
-
- if (image_get_magic(hdr) != IH_MAGIC) {
- puts (" Bad Magic Number\n");
- return 1;
- }
-
- len = image_get_header_size();
-
- checksum = image_get_hcrc(hdr);
- hdr->ih_hcrc = 0;
-
- if (crc32 (0, hdr, len) != checksum) {
- puts (" Bad Header Checksum\n");
- return 1;
- }
-
- image_print_contents(hdr, NULL);
-
- return 0;
-}
-
-static int do_iminfo(struct command *cmdtp, int argc, char *argv[])
-{
- int rcode = 1;
- int fd;
- int ret;
- image_header_t hdr;
-
- if (argc != 2)
- return COMMAND_ERROR_USAGE;
-
- fd = open(argv[1], O_RDONLY);
- if (fd < 0) {
- perror("open");
- return 1;
- }
-
- ret = read(fd, &hdr, sizeof(image_header_t));
- if (ret != sizeof(image_header_t))
- goto err_out;
-
- printf("Image at %s:\n", argv[1]);
- image_info(&hdr);
-
-err_out:
- close(fd);
-
- return rcode;
-}
-
-BAREBOX_CMD_HELP_START(iminfo)
-BAREBOX_CMD_HELP_USAGE("iminfo\n")
-BAREBOX_CMD_HELP_SHORT("Print header information for an application image.\n")
-BAREBOX_CMD_HELP_END
-
-BAREBOX_CMD_START(iminfo)
- .cmd = do_iminfo,
- .usage = "print header information for an application image",
- BAREBOX_CMD_HELP(cmd_iminfo_help)
-BAREBOX_CMD_END
diff --git a/commands/uimage.c b/commands/uimage.c
new file mode 100644
index 0000000000..82efd78349
--- /dev/null
+++ b/commands/uimage.c
@@ -0,0 +1,108 @@
+#include <common.h>
+#include <command.h>
+#include <image.h>
+#include <libbb.h>
+#include <fcntl.h>
+#include <fs.h>
+#include <malloc.h>
+#include <errno.h>
+#include <getopt.h>
+
+static int uimage_fd;
+
+static int uimage_flush(void *buf, unsigned int len)
+{
+ int ret;
+
+ ret = write_full(uimage_fd, buf, len);
+
+ return ret;
+}
+
+static int do_uimage(struct command *cmdtp, int argc, char *argv[])
+{
+ struct uimage_handle *handle;
+ int ret;
+ int verify = 0;
+ int fd;
+ int opt;
+ char *extract = NULL;
+ int info = 0;
+ int image_no = 0;
+
+ while ((opt = getopt(argc, argv, "ve:in:")) > 0) {
+ switch (opt) {
+ case 'v':
+ verify = 1;
+ break;
+ case 'i':
+ info = 1;
+ break;
+ case 'e':
+ extract = optarg;
+ break;
+ case 'n':
+ image_no = simple_strtoul(optarg, NULL, 0);
+ break;
+ }
+ }
+
+ if (optind == argc)
+ return COMMAND_ERROR_USAGE;
+
+ handle = uimage_open(argv[optind]);
+ if (!handle)
+ return 1;
+
+ if (info) {
+ printf("Image at %s:\n", argv[optind]);
+ uimage_print_contents(handle);
+ }
+
+ if (verify) {
+ printf("verifying data crc... ");
+ ret = uimage_verify(handle);
+ if (ret) {
+ goto err;
+ printf("Bad Data CRC\n");
+ } else {
+ printf("ok\n");
+ }
+ }
+
+ if (extract) {
+ fd = open(extract, O_WRONLY | O_CREAT | O_TRUNC);
+ if (fd < 0) {
+ perror("open");
+ ret = fd;
+ goto err;
+ }
+ uimage_fd = fd;
+ ret = uimage_load(handle, image_no, uimage_flush);
+ if (ret) {
+ printf("loading uImage failed with %d\n", ret);
+ close(fd);
+ goto err;
+ }
+
+ close(fd);
+ }
+err:
+ uimage_close(handle);
+
+ return ret ? 1 : 0;
+}
+
+BAREBOX_CMD_HELP_START(uimage)
+BAREBOX_CMD_HELP_USAGE("uimage [OPTIONS] <file>\n")
+BAREBOX_CMD_HELP_OPT ("-i", "show information about image\n")
+BAREBOX_CMD_HELP_OPT ("-v", "verify image\n")
+BAREBOX_CMD_HELP_OPT ("-e <outfile>", "extract image to <outfile>\n")
+BAREBOX_CMD_HELP_OPT ("-n <no>", "use image number <no> in multifile images\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(uimage)
+ .cmd = do_uimage,
+ .usage = "extract/verify uImage",
+ BAREBOX_CMD_HELP(cmd_uimage_help)
+BAREBOX_CMD_END