diff mbox series

[U-Boot,3/7] cmd: bootimg: Add bootimg command

Message ID 20190919172822.8255-4-semen.protsenko@linaro.org
State Superseded
Delegated to: Tom Rini
Headers show
Series am57xx: Implement Android 10 boot flow | expand

Commit Message

Sam Protsenko Sept. 19, 2019, 5:28 p.m. UTC
This command can be used to extract fields and image payloads from
Android Boot Image. It can be used for example to implement boot flow
where dtb is taken from boot.img (as v2 incorporated dtb inside of
boot.img). Using this command, one can obtain needed dtb file from
boot.img in scripting manner, and then apply needed dtbo's (from "dtbo"
partition) on top of that, providing then the resulting image to bootm
command in order to boot the Android.

Also right now this command has the sub-command to get an address and
size of recovery dtbo from recovery image. It can be further parsed using
'dtimg' command and merged into dtb file (for non-A/B devices only, see
[1,2] for details).

[1] https://source.android.com/devices/bootloader/boot-image-header
[2] https://source.android.com/devices/architecture/dto/partitions

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 cmd/Kconfig   |   8 +++
 cmd/Makefile  |   1 +
 cmd/bootimg.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 186 insertions(+)
 create mode 100644 cmd/bootimg.c

Comments

Simon Glass Sept. 20, 2019, 5:45 p.m. UTC | #1
Hi,

On Thu, 19 Sep 2019 at 12:28, Sam Protsenko <semen.protsenko@linaro.org> wrote:
>
> This command can be used to extract fields and image payloads from
> Android Boot Image. It can be used for example to implement boot flow
> where dtb is taken from boot.img (as v2 incorporated dtb inside of
> boot.img). Using this command, one can obtain needed dtb file from
> boot.img in scripting manner, and then apply needed dtbo's (from "dtbo"
> partition) on top of that, providing then the resulting image to bootm
> command in order to boot the Android.
>
> Also right now this command has the sub-command to get an address and
> size of recovery dtbo from recovery image. It can be further parsed using
> 'dtimg' command and merged into dtb file (for non-A/B devices only, see
> [1,2] for details).
>
> [1] https://source.android.com/devices/bootloader/boot-image-header
> [2] https://source.android.com/devices/architecture/dto/partitions
>
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  cmd/Kconfig   |   8 +++
>  cmd/Makefile  |   1 +
>  cmd/bootimg.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 186 insertions(+)
>  create mode 100644 cmd/bootimg.c


Shouldn't this be a subcommand of avb?

Regards,
Simon
Igor Opaniuk Sept. 24, 2019, 6:36 a.m. UTC | #2
Hi Simon,

On Fri, Sep 20, 2019 at 8:45 PM Simon Glass <sjg@chromium.org> wrote:
>
> Hi,
>
> On Thu, 19 Sep 2019 at 12:28, Sam Protsenko <semen.protsenko@linaro.org> wrote:
> >
> > This command can be used to extract fields and image payloads from
> > Android Boot Image. It can be used for example to implement boot flow
> > where dtb is taken from boot.img (as v2 incorporated dtb inside of
> > boot.img). Using this command, one can obtain needed dtb file from
> > boot.img in scripting manner, and then apply needed dtbo's (from "dtbo"
> > partition) on top of that, providing then the resulting image to bootm
> > command in order to boot the Android.
> >
> > Also right now this command has the sub-command to get an address and
> > size of recovery dtbo from recovery image. It can be further parsed using
> > 'dtimg' command and merged into dtb file (for non-A/B devices only, see
> > [1,2] for details).
> >
> > [1] https://source.android.com/devices/bootloader/boot-image-header
> > [2] https://source.android.com/devices/architecture/dto/partitions
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> > ---
> >  cmd/Kconfig   |   8 +++
> >  cmd/Makefile  |   1 +
> >  cmd/bootimg.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 186 insertions(+)
> >  create mode 100644 cmd/bootimg.c
>
>
> Shouldn't this be a subcommand of avb?

I think there is some misunderstanding here, as avb
is used only for signature verification/roll-back protection, other
aspects of booting Android (parsing android boot image) are
handled by other commands (for instance, bootm).

Howewer, I think (IMHO) that `bootimg` isn't a good choice for the
command name , which major functionality is manipulating
dtb/dtbos.

>
> Regards,
> Simon
Sam Protsenko Sept. 24, 2019, 6:41 p.m. UTC | #3
Hi Igor,

On Mon, Sep 23, 2019 at 11:36 PM Igor Opaniuk <igor.opaniuk@gmail.com> wrote:
>
> Hi Simon,
>
> On Fri, Sep 20, 2019 at 8:45 PM Simon Glass <sjg@chromium.org> wrote:
> >
> > Hi,
> >
> > On Thu, 19 Sep 2019 at 12:28, Sam Protsenko <semen.protsenko@linaro.org> wrote:
> > >
> > > This command can be used to extract fields and image payloads from
> > > Android Boot Image. It can be used for example to implement boot flow
> > > where dtb is taken from boot.img (as v2 incorporated dtb inside of
> > > boot.img). Using this command, one can obtain needed dtb file from
> > > boot.img in scripting manner, and then apply needed dtbo's (from "dtbo"
> > > partition) on top of that, providing then the resulting image to bootm
> > > command in order to boot the Android.
> > >
> > > Also right now this command has the sub-command to get an address and
> > > size of recovery dtbo from recovery image. It can be further parsed using
> > > 'dtimg' command and merged into dtb file (for non-A/B devices only, see
> > > [1,2] for details).
> > >
> > > [1] https://source.android.com/devices/bootloader/boot-image-header
> > > [2] https://source.android.com/devices/architecture/dto/partitions
> > >
> > > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> > > ---
> > >  cmd/Kconfig   |   8 +++
> > >  cmd/Makefile  |   1 +
> > >  cmd/bootimg.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  3 files changed, 186 insertions(+)
> > >  create mode 100644 cmd/bootimg.c
> >
> >
> > Shouldn't this be a subcommand of avb?
>
> I think there is some misunderstanding here, as avb
> is used only for signature verification/roll-back protection, other
> aspects of booting Android (parsing android boot image) are
> handled by other commands (for instance, bootm).
>
> Howewer, I think (IMHO) that `bootimg` isn't a good choice for the
> command name , which major functionality is manipulating
> dtb/dtbos.
>

Actually, 'bootimg' manipulates only Android boot image, but new
Android Boot Image v2 happen to have DTB field. For DTBO files in
Android we already have 'dtimg' command.

Simon,

This command is not connected with AVB. It's only needed to obtain
Android Boot Image payloads. We can't integrate its functionality in
'bootm' command, because we would need to merge some DTBO files (from
'dtbo' partition) into DTB file obtained from boot image. And bootm
command can't possibly know which DTBO files vendor would like to use
(e.g. different DTBOs for different boards). That's why I came up with
'bootimg' command.

Actually I think that we should think about implementing
'boot_android' next. Because the boot script is becoming quite
cluttered. But we should have those tiny commands anyway, as it's
convenient for development and provides a more flexible way to boot
Android.

I'm having presentation today at Linaro Connect, highlighting new
Android boot scheme. Slides will be available at [1]. The Android boot
flow becomes more and more extensive, so I think it's time to start
discussion between community, Google and vendors w.r.t. this topic.
One point we should bring up is the possibility to use FIT image
instead of bunch of Android images. I hope this is discussable.

But for now I think we should stick to established Android boot
architecture, as it was published at [2] and mandatory for new devices
launching with Android 10.

Thanks!

[1] https://connect.linaro.org/resources/san19/san19-217/
[2] https://source.android.com/devices/bootloader

> >
> > Regards,
> > Simon
>
>
>
> --
> Best regards - Freundliche Grüsse - Meilleures salutations
>
> Igor Opaniuk
>
> mailto: igor.opaniuk@gmail.com
> skype: igor.opanyuk
> +380 (93) 836 40 67
> http://ua.linkedin.com/in/iopaniuk
Simon Glass Sept. 25, 2019, 7:14 p.m. UTC | #4
Hi Sam,

On Tue, 24 Sep 2019 at 11:41, Sam Protsenko <semen.protsenko@linaro.org> wrote:
>
> Hi Igor,
>
> On Mon, Sep 23, 2019 at 11:36 PM Igor Opaniuk <igor.opaniuk@gmail.com> wrote:
> >
> > Hi Simon,
> >
> > On Fri, Sep 20, 2019 at 8:45 PM Simon Glass <sjg@chromium.org> wrote:
> > >
> > > Hi,
> > >
> > > On Thu, 19 Sep 2019 at 12:28, Sam Protsenko <semen.protsenko@linaro.org> wrote:
> > > >
> > > > This command can be used to extract fields and image payloads from
> > > > Android Boot Image. It can be used for example to implement boot flow
> > > > where dtb is taken from boot.img (as v2 incorporated dtb inside of
> > > > boot.img). Using this command, one can obtain needed dtb file from
> > > > boot.img in scripting manner, and then apply needed dtbo's (from "dtbo"
> > > > partition) on top of that, providing then the resulting image to bootm
> > > > command in order to boot the Android.
> > > >
> > > > Also right now this command has the sub-command to get an address and
> > > > size of recovery dtbo from recovery image. It can be further parsed using
> > > > 'dtimg' command and merged into dtb file (for non-A/B devices only, see
> > > > [1,2] for details).
> > > >
> > > > [1] https://source.android.com/devices/bootloader/boot-image-header
> > > > [2] https://source.android.com/devices/architecture/dto/partitions
> > > >
> > > > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> > > > ---
> > > >  cmd/Kconfig   |   8 +++
> > > >  cmd/Makefile  |   1 +
> > > >  cmd/bootimg.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > > >  3 files changed, 186 insertions(+)
> > > >  create mode 100644 cmd/bootimg.c
> > >
> > >
> > > Shouldn't this be a subcommand of avb?
> >
> > I think there is some misunderstanding here, as avb
> > is used only for signature verification/roll-back protection, other
> > aspects of booting Android (parsing android boot image) are
> > handled by other commands (for instance, bootm).
> >
> > Howewer, I think (IMHO) that `bootimg` isn't a good choice for the
> > command name , which major functionality is manipulating
> > dtb/dtbos.
> >
>
> Actually, 'bootimg' manipulates only Android boot image, but new
> Android Boot Image v2 happen to have DTB field. For DTBO files in
> Android we already have 'dtimg' command.
>
> Simon,
>
> This command is not connected with AVB. It's only needed to obtain
> Android Boot Image payloads. We can't integrate its functionality in
> 'bootm' command, because we would need to merge some DTBO files (from
> 'dtbo' partition) into DTB file obtained from boot image. And bootm
> command can't possibly know which DTBO files vendor would like to use
> (e.g. different DTBOs for different boards). That's why I came up with
> 'bootimg' command.

OK, so can we say this is specific to Android. So perhaps 'boota' ?

Minor point - boom allows passing an image address rather than
requiring loadaddr to be set.

>
> Actually I think that we should think about implementing
> 'boot_android' next. Because the boot script is becoming quite
> cluttered. But we should have those tiny commands anyway, as it's
> convenient for development and provides a more flexible way to boot
> Android.

Agreed on both counts.

>
> I'm having presentation today at Linaro Connect, highlighting new
> Android boot scheme. Slides will be available at [1]. The Android boot
> flow becomes more and more extensive, so I think it's time to start
> discussion between community, Google and vendors w.r.t. this topic.
> One point we should bring up is the possibility to use FIT image
> instead of bunch of Android images. I hope this is discussable.

That sounds like a good idea.

>
> But for now I think we should stick to established Android boot
> architecture, as it was published at [2] and mandatory for new devices
> launching with Android 10.

OK. Let's make sure to add sandbox tests for new functionality too.


- SImon

>
> Thanks!
>
> [1] https://connect.linaro.org/resources/san19/san19-217/
> [2] https://source.android.com/devices/bootloader
>
> > >
> > > Regards,
> > > Simon
> >
> >
> >
> > --
> > Best regards - Freundliche Grüsse - Meilleures salutations
> >
> > Igor Opaniuk
> >
> > mailto: igor.opaniuk@gmail.com
> > skype: igor.opanyuk
> > +380 (93) 836 40 67
> > http://ua.linkedin.com/in/iopaniuk
Sam Protsenko Oct. 23, 2019, 2:14 p.m. UTC | #5
Hi Simon,

On Wed, Sep 25, 2019 at 10:15 PM Simon Glass <sjg@chromium.org> wrote:
>
> Hi Sam,
>
> On Tue, 24 Sep 2019 at 11:41, Sam Protsenko <semen.protsenko@linaro.org> wrote:
> >
> > Hi Igor,
> >
> > On Mon, Sep 23, 2019 at 11:36 PM Igor Opaniuk <igor.opaniuk@gmail.com> wrote:
> > >
> > > Hi Simon,
> > >
> > > On Fri, Sep 20, 2019 at 8:45 PM Simon Glass <sjg@chromium.org> wrote:
> > > >
> > > > Hi,
> > > >
> > > > On Thu, 19 Sep 2019 at 12:28, Sam Protsenko <semen.protsenko@linaro.org> wrote:
> > > > >
> > > > > This command can be used to extract fields and image payloads from
> > > > > Android Boot Image. It can be used for example to implement boot flow
> > > > > where dtb is taken from boot.img (as v2 incorporated dtb inside of
> > > > > boot.img). Using this command, one can obtain needed dtb file from
> > > > > boot.img in scripting manner, and then apply needed dtbo's (from "dtbo"
> > > > > partition) on top of that, providing then the resulting image to bootm
> > > > > command in order to boot the Android.
> > > > >
> > > > > Also right now this command has the sub-command to get an address and
> > > > > size of recovery dtbo from recovery image. It can be further parsed using
> > > > > 'dtimg' command and merged into dtb file (for non-A/B devices only, see
> > > > > [1,2] for details).
> > > > >
> > > > > [1] https://source.android.com/devices/bootloader/boot-image-header
> > > > > [2] https://source.android.com/devices/architecture/dto/partitions
> > > > >
> > > > > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> > > > > ---
> > > > >  cmd/Kconfig   |   8 +++
> > > > >  cmd/Makefile  |   1 +
> > > > >  cmd/bootimg.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > >  3 files changed, 186 insertions(+)
> > > > >  create mode 100644 cmd/bootimg.c
> > > >
> > > >
> > > > Shouldn't this be a subcommand of avb?
> > >
> > > I think there is some misunderstanding here, as avb
> > > is used only for signature verification/roll-back protection, other
> > > aspects of booting Android (parsing android boot image) are
> > > handled by other commands (for instance, bootm).
> > >
> > > Howewer, I think (IMHO) that `bootimg` isn't a good choice for the
> > > command name , which major functionality is manipulating
> > > dtb/dtbos.
> > >
> >
> > Actually, 'bootimg' manipulates only Android boot image, but new
> > Android Boot Image v2 happen to have DTB field. For DTBO files in
> > Android we already have 'dtimg' command.
> >
> > Simon,
> >
> > This command is not connected with AVB. It's only needed to obtain
> > Android Boot Image payloads. We can't integrate its functionality in
> > 'bootm' command, because we would need to merge some DTBO files (from
> > 'dtbo' partition) into DTB file obtained from boot image. And bootm
> > command can't possibly know which DTBO files vendor would like to use
> > (e.g. different DTBOs for different boards). That's why I came up with
> > 'bootimg' command.
>
> OK, so can we say this is specific to Android. So perhaps 'boota' ?
>

I'd like to keep 'bootimg' name, to not confuse this command with
actual boot commands. The 'bootimg' doesn't boot anything, it just
provides the means to work with the image which is called "boot
image".

> Minor point - boom allows passing an image address rather than
> requiring loadaddr to be set.
>

Good point. I have added 'set_addr' sub-command in v2, will send it soon.

> >
> > Actually I think that we should think about implementing
> > 'boot_android' next. Because the boot script is becoming quite
> > cluttered. But we should have those tiny commands anyway, as it's
> > convenient for development and provides a more flexible way to boot
> > Android.
>
> Agreed on both counts.
>
> >
> > I'm having presentation today at Linaro Connect, highlighting new
> > Android boot scheme. Slides will be available at [1]. The Android boot
> > flow becomes more and more extensive, so I think it's time to start
> > discussion between community, Google and vendors w.r.t. this topic.
> > One point we should bring up is the possibility to use FIT image
> > instead of bunch of Android images. I hope this is discussable.
>
> That sounds like a good idea.
>

Just in case, slides and video are available here:

    https://connect.linaro.org/resources/san19/san19-217/

> >
> > But for now I think we should stick to established Android boot
> > architecture, as it was published at [2] and mandatory for new devices
> > launching with Android 10.
>
> OK. Let's make sure to add sandbox tests for new functionality too.
>

Done, will send v2 soon. Thanks!

>
> - SImon
>
> >
> > Thanks!
> >
> > [1] https://connect.linaro.org/resources/san19/san19-217/
> > [2] https://source.android.com/devices/bootloader
> >
> > > >
> > > > Regards,
> > > > Simon
> > >
> > >
> > >
> > > --
> > > Best regards - Freundliche Grüsse - Meilleures salutations
> > >
> > > Igor Opaniuk
> > >
> > > mailto: igor.opaniuk@gmail.com
> > > skype: igor.opanyuk
> > > +380 (93) 836 40 67
> > > http://ua.linkedin.com/in/iopaniuk
diff mbox series

Patch

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 98647f58b7..37f3003c2b 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -305,6 +305,14 @@  config CMD_DTIMG
 	  files should be merged in one dtb further, which needs to be passed to
 	  the kernel, as part of a boot process.
 
+config CMD_BOOTIMG
+	bool "bootimg"
+	depends on ANDROID_BOOT_IMAGE
+	help
+	  Android Boot Image manipulation commands. Allows one to extract
+	  images contained in boot.img, like kernel, ramdisk, dtb, etc, and
+	  obtain corresponding meta-information from boot.img.
+
 config CMD_ELF
 	bool "bootelf, bootvx"
 	default y
diff --git a/cmd/Makefile b/cmd/Makefile
index ac843b4b16..bf15e38f41 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -48,6 +48,7 @@  ifdef CONFIG_POST
 obj-$(CONFIG_CMD_DIAG) += diag.o
 endif
 obj-$(CONFIG_CMD_DTIMG) += dtimg.o
+obj-$(CONFIG_CMD_BOOTIMG) += bootimg.o
 obj-$(CONFIG_CMD_ECHO) += echo.o
 obj-$(CONFIG_ENV_IS_IN_EEPROM) += eeprom.o
 obj-$(CONFIG_CMD_EEPROM) += eeprom.o
diff --git a/cmd/bootimg.c b/cmd/bootimg.c
new file mode 100644
index 0000000000..4ef405f99a
--- /dev/null
+++ b/cmd/bootimg.c
@@ -0,0 +1,177 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018 Linaro Ltd.
+ * Sam Protsenko <semen.protsenko@linaro.org>
+ */
+
+#include <android_image.h>
+#include <common.h>
+
+static int do_bootimg_ver(cmd_tbl_t *cmdtp, int flag, int argc,
+			  char * const argv[])
+{
+	const struct andr_img_hdr *hdr;
+	char buf[65];
+
+	if (argc != 2)
+		return CMD_RET_USAGE;
+
+	hdr = (const struct andr_img_hdr *)load_addr;
+	if (android_image_check_header(hdr)) {
+		printf("Error: Boot Image header is incorrect\n");
+		return CMD_RET_FAILURE;
+	}
+
+	snprintf(buf, sizeof(buf), "%u", hdr->header_version);
+	env_set(argv[1], buf);
+
+	return CMD_RET_SUCCESS;
+}
+
+static int do_bootimg_get_dtbo(cmd_tbl_t *cmdtp, int flag, int argc,
+			       char * const argv[])
+{
+	const struct andr_img_hdr *hdr;
+	char buf[65];
+	ulong addr;
+	u32 size;
+
+	if (argc < 2 || argc > 3)
+		return CMD_RET_USAGE;
+
+	hdr = (const struct andr_img_hdr *)load_addr;
+	if (!android_image_get_dtbo(hdr, &addr, &size))
+		return CMD_RET_FAILURE;
+
+	snprintf(buf, sizeof(buf), "%lx", addr);
+	env_set(argv[1], buf);
+
+	if (argc == 3) {
+		snprintf(buf, sizeof(buf), "%x", size);
+		env_set(argv[2], buf);
+	}
+
+	return CMD_RET_SUCCESS;
+}
+
+static int do_bootimg_dtb_dump(cmd_tbl_t *cmdtp, int flag, int argc,
+			       char * const argv[])
+{
+	const struct andr_img_hdr *hdr;
+
+	if (argc != 1)
+		return CMD_RET_USAGE;
+
+	hdr = (const struct andr_img_hdr *)load_addr;
+	if (android_image_print_dtb_contents(hdr))
+		return CMD_RET_FAILURE;
+
+	return CMD_RET_SUCCESS;
+}
+
+static int do_bootimg_dtb_load_addr(cmd_tbl_t *cmdtp, int flag, int argc,
+				    char * const argv[])
+{
+	const struct andr_img_hdr *hdr;
+	char buf[65];
+
+	if (argc != 2)
+		return CMD_RET_USAGE;
+
+	hdr = (const struct andr_img_hdr *)load_addr;
+	if (android_image_check_header(hdr)) {
+		printf("Error: Boot Image header is incorrect\n");
+		return CMD_RET_FAILURE;
+	}
+
+	if (hdr->header_version < 2) {
+		printf("Error: header_version must be >= 2 for this\n");
+		return CMD_RET_FAILURE;
+	}
+
+	snprintf(buf, sizeof(buf), "%lx", (ulong)hdr->dtb_addr);
+	env_set(argv[1], buf);
+
+	return CMD_RET_SUCCESS;
+}
+
+static int do_bootimg_get_dtb_file(cmd_tbl_t *cmdtp, int flag, int argc,
+				   char * const argv[])
+{
+	const struct andr_img_hdr *hdr;
+	char *endp;
+	char buf[65];
+	u32 index;
+	ulong addr;
+	u32 size;
+
+	if (argc < 3 || argc > 4)
+		return CMD_RET_USAGE;
+
+	index = simple_strtoul(argv[1], &endp, 0);
+	if (*endp != '\0') {
+		printf("Error: Wrong index\n");
+		return CMD_RET_FAILURE;
+	}
+
+	hdr = (const struct andr_img_hdr *)load_addr;
+	if (!android_image_get_dtb_by_index(hdr, index, &addr, &size))
+		return CMD_RET_FAILURE;
+
+	snprintf(buf, sizeof(buf), "%lx", addr);
+	env_set(argv[2], buf);
+
+	if (argc == 4) {
+		snprintf(buf, sizeof(buf), "%x", size);
+		env_set(argv[3], buf);
+	}
+
+	return CMD_RET_SUCCESS;
+}
+
+static cmd_tbl_t cmd_bootimg_sub[] = {
+	U_BOOT_CMD_MKENT(ver, 2, 1, do_bootimg_ver, "", ""),
+	U_BOOT_CMD_MKENT(get_dtbo, 3, 1, do_bootimg_get_dtbo, "", ""),
+	U_BOOT_CMD_MKENT(dtb_dump, 1, 1, do_bootimg_dtb_dump, "", ""),
+	U_BOOT_CMD_MKENT(dtb_load_addr, 2, 1, do_bootimg_dtb_load_addr, "", ""),
+	U_BOOT_CMD_MKENT(get_dtb_file, 4, 1, do_bootimg_get_dtb_file, "", ""),
+};
+
+static int do_bootimg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	cmd_tbl_t *cp;
+
+	cp = find_cmd_tbl(argv[1], cmd_bootimg_sub,
+			  ARRAY_SIZE(cmd_bootimg_sub));
+
+	/* Strip off leading 'bootimg' command argument */
+	argc--;
+	argv++;
+
+	if (!cp || argc > cp->maxargs)
+		return CMD_RET_USAGE;
+	if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
+		return CMD_RET_SUCCESS;
+
+	return cp->cmd(cmdtp, flag, argc, argv);
+}
+
+U_BOOT_CMD(
+	bootimg, CONFIG_SYS_MAXARGS, 0, do_bootimg,
+	"manipulate Android Boot Image (must reside in $loadaddr)",
+	"ver <varname>\n"
+	"    - get header version\n"
+	"bootimg get_dtbo <addr_var> [size_var]\n"
+	"    - get address and size (hex) of recovery DTBO area in the image\n"
+	"      <addr_var>: variable name to contain DTBO area address\n"
+	"      [size_var]: variable name to contain DTBO area size\n"
+	"bootimg dtb_dump\n"
+	"    - print info for all files in DTB area\n"
+	"bootimg dtb_load_addr <varname>\n"
+	"    - get load address (hex) of DTB\n"
+	"bootimg get_dtb_file <index> <addr_var> [size_var]\n"
+	"    - get address and size (hex) of DTB file in the image\n"
+	"      <index>: index of desired DTB file in DTB area\n"
+	"      <addr_var>: variable name to contain DTB file address\n"
+	"      [size_var]: variable name to contain DTB file size\n"
+);