diff mbox series

[U-Boot,v4,2/2] cmd: Add dtimg command

Message ID 20180816203413.1598-2-semen.protsenko@linaro.org
State Accepted
Commit d03e76af5ce343d9bae253b7604b2d9334d40a46
Delegated to: Tom Rini
Headers show
Series [U-Boot,v4,1/2] common: Add support for Android DT image | expand

Commit Message

Sam Protsenko Aug. 16, 2018, 8:34 p.m. UTC
dtimg command allows user to work with Android DTB/DTBO image format.
Such as, getting the address of desired DTB/DTBO file, printing the dump
of the image in U-Boot shell, etc.

This command is needed to provide Android boot with new Android DT image
format further.

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
Changes in v4:
  - rebased
  - fixed SPDX tags
  - use obj-$(CONFIG_CMD_DTIMG) instead #ifdef

 cmd/Kconfig     |   8 +++
 cmd/Makefile    |   1 +
 cmd/dtimg.c     | 141 ++++++++++++++++++++++++++++++++++++++++++++++++
 common/Makefile |   2 +
 4 files changed, 152 insertions(+)
 create mode 100644 cmd/dtimg.c

Comments

Tom Rini Aug. 16, 2018, 8:49 p.m. UTC | #1
On Thu, Aug 16, 2018 at 11:34:13PM +0300, Sam Protsenko wrote:

> dtimg command allows user to work with Android DTB/DTBO image format.
> Such as, getting the address of desired DTB/DTBO file, printing the dump
> of the image in U-Boot shell, etc.
> 
> This command is needed to provide Android boot with new Android DT image
> format further.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>

Reviewed-by: Tom Rini <trini@konsulko.com>
Tom Rini Aug. 20, 2018, 5:41 p.m. UTC | #2
On Thu, Aug 16, 2018 at 11:34:13PM +0300, Sam Protsenko wrote:

> dtimg command allows user to work with Android DTB/DTBO image format.
> Such as, getting the address of desired DTB/DTBO file, printing the dump
> of the image in U-Boot shell, etc.
> 
> This command is needed to provide Android boot with new Android DT image
> format further.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> Reviewed-by: Tom Rini <trini@konsulko.com>

Applied to u-boot/master, thanks!
Eugeniu Rosca Nov. 12, 2019, 6:18 p.m. UTC | #3
Hello Sam,

On Thu, Aug 16, 2018 at 11:34:13PM +0300, Sam Protsenko wrote:
> dtimg command allows user to work with Android DTB/DTBO image format.
> Such as, getting the address of desired DTB/DTBO file, printing the dump
> of the image in U-Boot shell, etc.
> 
> This command is needed to provide Android boot with new Android DT image
> format further.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> Reviewed-by: Tom Rini <trini@konsulko.com>

[..]

> +U_BOOT_CMD(
> +	dtimg, CONFIG_SYS_MAXARGS, 0, do_dtimg,
> +	"manipulate dtb/dtbo Android image",
> +	"dump <addr>\n"
> +	"    - parse specified image and print its structure info\n"
> +	"      <addr>: image address in RAM, in hex\n"
> +	"dtimg start <addr> <index> <varname>\n"
> +	"    - get address (hex) of FDT in the image, by index\n"
> +	"      <addr>: image address in RAM, in hex\n"
> +	"      <index>: index of desired FDT in the image\n"
> +	"      <varname>: name of variable where to store address of FDT\n"
> +	"dtimg size <addr> <index> <varname>\n"
> +	"    - get size (hex, bytes) of FDT in the image, by index\n"
> +	"      <addr>: image address in RAM, in hex\n"
> +	"      <index>: index of desired FDT in the image\n"
> +	"      <varname>: name of variable where to store size of FDT"
> +);

Since you are the author and the main stakeholder of "dtimg", could you
kindly feedback the command usage you envision for getting the start and
size of dtb/dtbo blob given a certain "id" and "rev" fields used by
mkdtboimg.py [1] and visible in the output of U-Boot's "dtimg dump" [2]?

One option would be to extend the existing "dtimg {start|size}" to
accept an argument like "id:<val>" and "rev:<val>".

Another possibility is to create brand new dtimg sub-command.
What would be your preference? TIA.

[1] https://android.googlesource.com/platform/system/libufdt/+/master/utils/src/mkdtboimg.py
[2] https://gitlab.denx.de/u-boot/u-boot/commit/e63bf1b13b3a7a
Roman Stratiienko Nov. 13, 2019, 10:19 a.m. UTC | #4
On Tue, Nov 12, 2019 at 8:18 PM Eugeniu Rosca <erosca@de.adit-jv.com> wrote:
>
> Hello Sam,
>
> On Thu, Aug 16, 2018 at 11:34:13PM +0300, Sam Protsenko wrote:
> > dtimg command allows user to work with Android DTB/DTBO image format.
> > Such as, getting the address of desired DTB/DTBO file, printing the dump
> > of the image in U-Boot shell, etc.
> >
> > This command is needed to provide Android boot with new Android DT image
> > format further.
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> > Reviewed-by: Tom Rini <trini@konsulko.com>
>
> [..]
>
> > +U_BOOT_CMD(
> > +     dtimg, CONFIG_SYS_MAXARGS, 0, do_dtimg,
> > +     "manipulate dtb/dtbo Android image",
> > +     "dump <addr>\n"
> > +     "    - parse specified image and print its structure info\n"
> > +     "      <addr>: image address in RAM, in hex\n"
> > +     "dtimg start <addr> <index> <varname>\n"
> > +     "    - get address (hex) of FDT in the image, by index\n"
> > +     "      <addr>: image address in RAM, in hex\n"
> > +     "      <index>: index of desired FDT in the image\n"
> > +     "      <varname>: name of variable where to store address of FDT\n"
> > +     "dtimg size <addr> <index> <varname>\n"
> > +     "    - get size (hex, bytes) of FDT in the image, by index\n"
> > +     "      <addr>: image address in RAM, in hex\n"
> > +     "      <index>: index of desired FDT in the image\n"
> > +     "      <varname>: name of variable where to store size of FDT"
> > +);
>
> Since you are the author and the main stakeholder of "dtimg", could you
> kindly feedback the command usage you envision for getting the start and
> size of dtb/dtbo blob given a certain "id" and "rev" fields used by
> mkdtboimg.py [1] and visible in the output of U-Boot's "dtimg dump" [2]?
>
> One option would be to extend the existing "dtimg {start|size}" to
> accept an argument like "id:<val>" and "rev:<val>".
>
> Another possibility is to create brand new dtimg sub-command.
> What would be your preference? TIA.
>
> [1] https://android.googlesource.com/platform/system/libufdt/+/master/utils/src/mkdtboimg.py
> [2] https://gitlab.denx.de/u-boot/u-boot/commit/e63bf1b13b3a7a

Let me add some background information to clarify why new command was suggested.
We came up with this during brainstorming on what is the best way to
implement lookup fdt by id and rev fields.

First suggestion was to implement separate lookup command, e.g.:

--> dtimg lookup id:<board_id> <dt_image_index_variable>

Second one was to integrate it into existing start/size command to
make command look more natural:

--> dtimg start|size <addr> [<index>|id:<id>] <varname>

Then after some time I suggested to combine 'start/size' subcommands
into single 'range' subcommand:

--> dtimg range <addr> id:<id> [rev:<rev>] [<start_varname> [<size_varname>]]
--> dtimg range <addr> index:<index> [<start_varname> [<size_varname>]]

Benefits of such combining:
- Reduce chance of human mistake in between of this commands (for
example different values for start and size).
- Increase readability and slightly reduce parsing time.

Downsides:
This solution is a little revolutionary since it requires to start
long-term deprecation process of start/size subcommands.

So the main question to the community is next:
Are we ready to make long term deprecation in the name of benefits
mentioned above?

In case not - we have no other choice but to extend existing
start/size subcommands.
Eugeniu Rosca Nov. 13, 2019, 10:58 p.m. UTC | #5
Hi Roman,
(CC-ing Igor for Android topics)

On Wed, Nov 13, 2019 at 12:19:59PM +0200, Roman Stratiienko wrote:
> On Tue, Nov 12, 2019 at 8:18 PM Eugeniu Rosca <erosca@de.adit-jv.com> wrote:
> >
> > Hello Sam,
> >
> > On Thu, Aug 16, 2018 at 11:34:13PM +0300, Sam Protsenko wrote:
> > > dtimg command allows user to work with Android DTB/DTBO image format.
> > > Such as, getting the address of desired DTB/DTBO file, printing the dump
> > > of the image in U-Boot shell, etc.

[..]

> > Since you are the author and the main stakeholder of "dtimg", could you
> > kindly feedback the command usage you envision for getting the start and
> > size of dtb/dtbo blob given a certain "id" and "rev" fields used by
> > mkdtboimg.py [1] and visible in the output of U-Boot's "dtimg dump" [2]?
> >
> > One option would be to extend the existing "dtimg {start|size}" to
> > accept an argument like "id:<val>" and "rev:<val>".
> >
> > Another possibility is to create brand new dtimg sub-command.
> > What would be your preference? TIA.
> >
> > [1] https://android.googlesource.com/platform/system/libufdt/+/master/utils/src/mkdtboimg.py
> > [2] https://gitlab.denx.de/u-boot/u-boot/commit/e63bf1b13b3a7a
> 
> Let me add some background information to clarify why new command was suggested.
> We came up with this during brainstorming on what is the best way to
> implement lookup fdt by id and rev fields.
> 
> First suggestion was to implement separate lookup command, e.g.:
> 
> --> dtimg lookup id:<board_id> <dt_image_index_variable>
> 
> Second one was to integrate it into existing start/size command to
> make command look more natural:
> 
> --> dtimg start|size <addr> [<index>|id:<id>] <varname>
> 
> Then after some time I suggested to combine 'start/size' subcommands
> into single 'range' subcommand:
> 
> --> dtimg range <addr> id:<id> [rev:<rev>] [<start_varname> [<size_varname>]]
> --> dtimg range <addr> index:<index> [<start_varname> [<size_varname>]]
> 
> Benefits of such combining:
> - Reduce chance of human mistake in between of this commands (for
> example different values for start and size).
> - Increase readability and slightly reduce parsing time.
> 
> Downsides:
> This solution is a little revolutionary since it requires to start
> long-term deprecation process of start/size subcommands.

So, what you are proposing is to migrate away from the "start" and
"size" sub-commands in the long run. While I understand the good
intentions, let me share my opinion what this means for platform
maintainers like us.

As a platform maintainer, it is not uncommon to encounter a scenario
like below:
 - platform X reached "feature freeze" one year ago with U-Boot v2018.11
 - platform Y reaches "feature freeze" soon with U-Boot v2020.01

If "dtimg" is used in both platforms and the command usage is not
backward compatible, this generates all kind of overhead like the need
to maintain two different versions of boot scripts (in case you keep
track of them externally as text files, which is what we do).

This is hugely simplified involving one single command. Imagine
several U-Boot commands fundamentally changing their usage pattern
over time. Things would become pretty messy.

> 
> So the main question to the community is next:
> Are we ready to make long term deprecation in the name of benefits
> mentioned above?

I hope more people will feedback on that, but in my opinion, we have to
honor the existing "dtimg" usage as a blueprint and carefully add
backward-compatible changes to it. This roughly translates to, IMHO:
 - in case of adding a brand new sub-command, it must not overlap in
   its function with any of pre-existing sub-commands
 - in case of enriching/extending a pre-existing sub-command, it only
   sounds appropriate to me adding one or more _optional_ arguments to
   maintain backward compatibility

Both above points can be met if "dtimg {start|size}" is modified as
follows, to account for the "id" and "rev" fields:

 -> dtimg start|size <addr> <index> [id:<id>] [rev:<rev>] <varname>

Some usage examples derived from the above proposal:

 -> dtimg start|size <addr> <index> <varname> 
    current behavior
 -> dtimg start|size <addr> <index> id:<id> <varname> 
    get the "start|size" of the blob carrying "id" value <id>. Assuming
    there are several such blobs in the image, get the <index>th one
 -> dtimg start|size <addr> <index> rev:<rev> <varname> 
    get the "start|size" of the blob carrying "rev" value <rev>.
    Assuming there are several such blobs, get the <index>th one
 -> dtimg start|size <addr> <index> id:<id> rev:<rev> <varname> 
    get the "start|size" of the blob carrying "id" value <id> AND "rev"
    value <rev>. Assuming several such blobs, get the <index>th one

> 
> In case not - we have no other choice but to extend existing
> start/size subcommands.
Eugeniu Rosca Nov. 18, 2019, 9:27 p.m. UTC | #6
Hello Igor, hello Sam,

We still have high hopes getting your response to
https://patchwork.ozlabs.org/patch/958594/#2302310

If not given, we will proceed with implementing the proposal from
https://patchwork.ozlabs.org/patch/958594/#2303657
Eugeniu Rosca Dec. 2, 2019, 2:26 p.m. UTC | #7
Dear Igor and Sam,
Cc: Tom, Simon

On Mon, Nov 18, 2019 at 10:27:32PM +0100, Eugeniu Rosca wrote:
> Hello Igor, hello Sam,
> 
> We still have high hopes getting your response to
> https://patchwork.ozlabs.org/patch/958594/#2302310
> 
> If not given, we will proceed with implementing the proposal from
> https://patchwork.ozlabs.org/patch/958594/#2303657

As the ones responsible for Android-specific patches, would you kindly
review the functionality submitted to
https://patchwork.ozlabs.org/cover/1202575/ ?

In case you are not available in the next weeks, I hope Tom and Simon
will suggest a way to go forward with the new patches?
Sam Protsenko Dec. 2, 2019, 7:23 p.m. UTC | #8
Hi Eugeniu,

On Thu, Nov 14, 2019 at 12:58 AM Eugeniu Rosca <roscaeugeniu@gmail.com> wrote:
>
> Hi Roman,
> (CC-ing Igor for Android topics)
>
> On Wed, Nov 13, 2019 at 12:19:59PM +0200, Roman Stratiienko wrote:
> > On Tue, Nov 12, 2019 at 8:18 PM Eugeniu Rosca <erosca@de.adit-jv.com> wrote:
> > >
> > > Hello Sam,
> > >
> > > On Thu, Aug 16, 2018 at 11:34:13PM +0300, Sam Protsenko wrote:
> > > > dtimg command allows user to work with Android DTB/DTBO image format.
> > > > Such as, getting the address of desired DTB/DTBO file, printing the dump
> > > > of the image in U-Boot shell, etc.
>
> [..]
>
> > > Since you are the author and the main stakeholder of "dtimg", could you
> > > kindly feedback the command usage you envision for getting the start and
> > > size of dtb/dtbo blob given a certain "id" and "rev" fields used by
> > > mkdtboimg.py [1] and visible in the output of U-Boot's "dtimg dump" [2]?
> > >
> > > One option would be to extend the existing "dtimg {start|size}" to
> > > accept an argument like "id:<val>" and "rev:<val>".
> > >
> > > Another possibility is to create brand new dtimg sub-command.
> > > What would be your preference? TIA.
> > >
> > > [1] https://android.googlesource.com/platform/system/libufdt/+/master/utils/src/mkdtboimg.py
> > > [2] https://gitlab.denx.de/u-boot/u-boot/commit/e63bf1b13b3a7a
> >
> > Let me add some background information to clarify why new command was suggested.
> > We came up with this during brainstorming on what is the best way to
> > implement lookup fdt by id and rev fields.
> >
> > First suggestion was to implement separate lookup command, e.g.:
> >
> > --> dtimg lookup id:<board_id> <dt_image_index_variable>
> >
> > Second one was to integrate it into existing start/size command to
> > make command look more natural:
> >
> > --> dtimg start|size <addr> [<index>|id:<id>] <varname>
> >
> > Then after some time I suggested to combine 'start/size' subcommands
> > into single 'range' subcommand:
> >
> > --> dtimg range <addr> id:<id> [rev:<rev>] [<start_varname> [<size_varname>]]
> > --> dtimg range <addr> index:<index> [<start_varname> [<size_varname>]]
> >
> > Benefits of such combining:
> > - Reduce chance of human mistake in between of this commands (for
> > example different values for start and size).
> > - Increase readability and slightly reduce parsing time.
> >
> > Downsides:
> > This solution is a little revolutionary since it requires to start
> > long-term deprecation process of start/size subcommands.
>
> So, what you are proposing is to migrate away from the "start" and
> "size" sub-commands in the long run. While I understand the good
> intentions, let me share my opinion what this means for platform
> maintainers like us.
>
> As a platform maintainer, it is not uncommon to encounter a scenario
> like below:
>  - platform X reached "feature freeze" one year ago with U-Boot v2018.11
>  - platform Y reaches "feature freeze" soon with U-Boot v2020.01
>
> If "dtimg" is used in both platforms and the command usage is not
> backward compatible, this generates all kind of overhead like the need
> to maintain two different versions of boot scripts (in case you keep
> track of them externally as text files, which is what we do).
>
> This is hugely simplified involving one single command. Imagine
> several U-Boot commands fundamentally changing their usage pattern
> over time. Things would become pretty messy.
>
> >
> > So the main question to the community is next:
> > Are we ready to make long term deprecation in the name of benefits
> > mentioned above?
>
> I hope more people will feedback on that, but in my opinion, we have to
> honor the existing "dtimg" usage as a blueprint and carefully add
> backward-compatible changes to it. This roughly translates to, IMHO:
>  - in case of adding a brand new sub-command, it must not overlap in
>    its function with any of pre-existing sub-commands
>  - in case of enriching/extending a pre-existing sub-command, it only
>    sounds appropriate to me adding one or more _optional_ arguments to
>    maintain backward compatibility
>

We should never change any commands (user interface), unless they are
deprecated / completely broken / etc. So although it might be seen as
more logical to modify existing 'dtimg' commands, we shouldn't do that
if it's breaking existing user interfaces. It's similar to golden
kernel rule ("we don't break user space"). Hence new sub-commands
(probably) should be added. Sorry, I didn't have much time to read the
whole discussion yet. But please stick to next two rules:

   1. Don't break existing interface; change it only in
backward-compatible manner
   2. Don't introduce non-standard extensions or non-standard
usage/namings to 'dtimg'. If you add some functionality, it must be
present in official Android DTBO format documentation, and we should
stick to namings suggested there.

Not asking that as 'dtimg' original author (it doesn't matter much),
but I think it's just a common sense in projects as big as U-Boot or
Linux kernel. And you correctly pointed out all possible implications,
so I have nothing to add on that matter.

I'm gonna review the whole discussion and associated patches in the
next few days, so maybe you'll hear more valuable feedback from me
soon.

Also, we'll surely need to sync up on our patch series, as my Android
Boot patches also make use of some 'dtimg' functionality.
Unfortunately, I don't have much time left on my current project, so
I'd really like to get my pending patches merged until then.

Thanks!

> Both above points can be met if "dtimg {start|size}" is modified as
> follows, to account for the "id" and "rev" fields:
>
>  -> dtimg start|size <addr> <index> [id:<id>] [rev:<rev>] <varname>
>
> Some usage examples derived from the above proposal:
>
>  -> dtimg start|size <addr> <index> <varname>
>     current behavior
>  -> dtimg start|size <addr> <index> id:<id> <varname>
>     get the "start|size" of the blob carrying "id" value <id>. Assuming
>     there are several such blobs in the image, get the <index>th one
>  -> dtimg start|size <addr> <index> rev:<rev> <varname>
>     get the "start|size" of the blob carrying "rev" value <rev>.
>     Assuming there are several such blobs, get the <index>th one
>  -> dtimg start|size <addr> <index> id:<id> rev:<rev> <varname>
>     get the "start|size" of the blob carrying "id" value <id> AND "rev"
>     value <rev>. Assuming several such blobs, get the <index>th one
>
> >
> > In case not - we have no other choice but to extend existing
> > start/size subcommands.
>
> --
> Best Regards,
> Eugeniu
diff mbox series

Patch

diff --git a/cmd/Kconfig b/cmd/Kconfig
index bd90946667..b9215abae3 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -254,6 +254,14 @@  config CMD_BOOTMENU
 	help
 	  Add an ANSI terminal boot menu command.
 
+config CMD_DTIMG
+	bool "dtimg"
+	help
+	  Android DTB/DTBO image manipulation commands. Read dtb/dtbo files from
+	  image into RAM, dump image structure information, etc. Those dtb/dtbo
+	  files should be merged in one dtb further, which needs to be passed to
+	  the kernel, as part of a boot process.
+
 config CMD_ELF
 	bool "bootelf, bootvx"
 	default y
diff --git a/cmd/Makefile b/cmd/Makefile
index 12d2118f1d..b1206fca85 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -43,6 +43,7 @@  ifdef CONFIG_POST
 obj-$(CONFIG_CMD_DIAG) += diag.o
 endif
 obj-$(CONFIG_CMD_DISPLAY) += display.o
+obj-$(CONFIG_CMD_DTIMG) += dtimg.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/dtimg.c b/cmd/dtimg.c
new file mode 100644
index 0000000000..65c8d101b9
--- /dev/null
+++ b/cmd/dtimg.c
@@ -0,0 +1,141 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018 Linaro Ltd.
+ * Sam Protsenko <semen.protsenko@linaro.org>
+ */
+
+#include <image-android-dt.h>
+#include <common.h>
+
+enum cmd_dtimg_info {
+	CMD_DTIMG_START = 0,
+	CMD_DTIMG_SIZE,
+};
+
+static int do_dtimg_dump(cmd_tbl_t *cmdtp, int flag, int argc,
+			 char * const argv[])
+{
+	char *endp;
+	ulong hdr_addr;
+
+	if (argc != 2)
+		return CMD_RET_USAGE;
+
+	hdr_addr = simple_strtoul(argv[1], &endp, 16);
+	if (*endp != '\0') {
+		printf("Error: Wrong image address\n");
+		return CMD_RET_FAILURE;
+	}
+
+	if (!android_dt_check_header(hdr_addr)) {
+		printf("Error: DT image header is incorrect\n");
+		return CMD_RET_FAILURE;
+	}
+
+	android_dt_print_contents(hdr_addr);
+
+	return CMD_RET_SUCCESS;
+}
+
+static int dtimg_get_fdt(int argc, char * const argv[], enum cmd_dtimg_info cmd)
+{
+	ulong hdr_addr;
+	u32 index;
+	char *endp;
+	ulong fdt_addr;
+	u32 fdt_size;
+	char buf[65];
+
+	if (argc != 4)
+		return CMD_RET_USAGE;
+
+	hdr_addr = simple_strtoul(argv[1], &endp, 16);
+	if (*endp != '\0') {
+		printf("Error: Wrong image address\n");
+		return CMD_RET_FAILURE;
+	}
+
+	if (!android_dt_check_header(hdr_addr)) {
+		printf("Error: DT image header is incorrect\n");
+		return CMD_RET_FAILURE;
+	}
+
+	index = simple_strtoul(argv[2], &endp, 0);
+	if (*endp != '\0') {
+		printf("Error: Wrong index\n");
+		return CMD_RET_FAILURE;
+	}
+
+	if (!android_dt_get_fdt_by_index(hdr_addr, index, &fdt_addr, &fdt_size))
+		return CMD_RET_FAILURE;
+
+	switch (cmd) {
+	case CMD_DTIMG_START:
+		snprintf(buf, sizeof(buf), "%lx", fdt_addr);
+		break;
+	case CMD_DTIMG_SIZE:
+		snprintf(buf, sizeof(buf), "%x", fdt_size);
+		break;
+	default:
+		printf("Error: Unknown cmd_dtimg_info value: %d\n", cmd);
+		return CMD_RET_FAILURE;
+	}
+
+	env_set(argv[3], buf);
+
+	return CMD_RET_SUCCESS;
+}
+
+static int do_dtimg_start(cmd_tbl_t *cmdtp, int flag, int argc,
+			  char * const argv[])
+{
+	return dtimg_get_fdt(argc, argv, CMD_DTIMG_START);
+}
+
+static int do_dtimg_size(cmd_tbl_t *cmdtp, int flag, int argc,
+			 char * const argv[])
+{
+	return dtimg_get_fdt(argc, argv, CMD_DTIMG_SIZE);
+}
+
+static cmd_tbl_t cmd_dtimg_sub[] = {
+	U_BOOT_CMD_MKENT(dump, 2, 0, do_dtimg_dump, "", ""),
+	U_BOOT_CMD_MKENT(start, 4, 0, do_dtimg_start, "", ""),
+	U_BOOT_CMD_MKENT(size, 4, 0, do_dtimg_size, "", ""),
+};
+
+static int do_dtimg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	cmd_tbl_t *cp;
+
+	cp = find_cmd_tbl(argv[1], cmd_dtimg_sub, ARRAY_SIZE(cmd_dtimg_sub));
+
+	/* Strip off leading 'dtimg' command argument */
+	argc--;
+	argv++;
+
+	if (!cp || argc > cp->maxargs)
+		return CMD_RET_USAGE;
+	if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
+		return CMD_RET_SUCCESS;
+
+	return cp->cmd(cmdtp, flag, argc, argv);
+}
+
+U_BOOT_CMD(
+	dtimg, CONFIG_SYS_MAXARGS, 0, do_dtimg,
+	"manipulate dtb/dtbo Android image",
+	"dump <addr>\n"
+	"    - parse specified image and print its structure info\n"
+	"      <addr>: image address in RAM, in hex\n"
+	"dtimg start <addr> <index> <varname>\n"
+	"    - get address (hex) of FDT in the image, by index\n"
+	"      <addr>: image address in RAM, in hex\n"
+	"      <index>: index of desired FDT in the image\n"
+	"      <varname>: name of variable where to store address of FDT\n"
+	"dtimg size <addr> <index> <varname>\n"
+	"    - get size (hex, bytes) of FDT in the image, by index\n"
+	"      <addr>: image address in RAM, in hex\n"
+	"      <index>: index of desired FDT in the image\n"
+	"      <varname>: name of variable where to store size of FDT"
+);
diff --git a/common/Makefile b/common/Makefile
index 7100541ece..7473b85011 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -108,6 +108,8 @@  obj-$(CONFIG_IO_TRACE) += iotrace.o
 obj-y += memsize.o
 obj-y += stdio.o
 
+obj-$(CONFIG_CMD_DTIMG) += image-android-dt.o
+
 ifdef CONFIG_CMD_EEPROM_LAYOUT
 obj-y += eeprom/eeprom_field.o eeprom/eeprom_layout.o
 endif