Patchwork [U-Boot,v3,2/6] fdt: Add support for embedded device tree (CONFIG_OF_EMBED)

login
register
mail settings
Submitter Simon Glass
Date Oct. 11, 2011, 10:26 p.m.
Message ID <1318371971-4457-3-git-send-email-sjg@chromium.org>
Download mbox | patch
Permalink /patch/119076/
State New, archived
Headers show

Comments

Simon Glass - Oct. 11, 2011, 10:26 p.m.
This new option allows U-Boot to embed a binary device tree into its image
to allow run-time control of peripherals. This device tree is for U-Boot's
own use and is not necessarily the same one as is passed to the kernel.

The device tree compiler output should be placed in the $(obj)
rooted tree. Since $(OBJCOPY) insists on adding the path to the
generated symbol names, to ensure consistency it should be
invoked from the directory where the .dtb file is located and
given the input file name without the path.

This commit contains my entry for the ugliest Makefile / shell interaction
competition.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Move fdt files into board/<vendor>/dts
- Provide access to ARCH_CPU_DTS which is the CPU's base device tree

 Makefile         |    4 ++
 README           |   11 ++++-
 config.mk        |    1 +
 dts/Makefile     |  109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/common.h |    1 +
 5 files changed, 124 insertions(+), 2 deletions(-)
 create mode 100644 dts/Makefile
Stephen Warren - Oct. 13, 2011, 9:13 p.m.
Simon Glass wrote at Tuesday, October 11, 2011 4:26 PM:
> This new option allows U-Boot to embed a binary device tree into its image
> to allow run-time control of peripherals. This device tree is for U-Boot's
> own use and is not necessarily the same one as is passed to the kernel.
...
> diff --git a/dts/Makefile b/dts/Makefile
...
> +$(DT_BIN): $(TOPDIR)/board/$(VENDOR)/dts/$(DEVICE_TREE).dts
> +	cat $< | $(CPP) -P $(DTS_CPPFLAGS) - >$@.tmp

Couldn't that just be:

	$(CPP) -P $(DTS_CPPFLAGS) $< >$@.tmp

> +	$(DTC) -R 4 -p 0x1000 -O dtb -o ${DT_BIN} $@.tmp
> +	rm $@.tmp
Stephen Warren - Oct. 13, 2011, 9:21 p.m.
Simon Glass wrote at Tuesday, October 11, 2011 4:26 PM:
> This new option allows U-Boot to embed a binary device tree into its image
> to allow run-time control of peripherals. This device tree is for U-Boot's
> own use and is not necessarily the same one as is passed to the kernel.
> 
> The device tree compiler output should be placed in the $(obj)
> rooted tree. Since $(OBJCOPY) insists on adding the path to the
> generated symbol names, to ensure consistency it should be
> invoked from the directory where the .dtb file is located and
> given the input file name without the path.
...
> +process_lds = \
> +	$(1) | sed -r -n 's/^OUTPUT_$(2)[ ("]*([^")]*).*/\1/p'
> +
> +# Run the compiler and get the link script from the linker
> +GET_LDS = $(CC) $(CFLAGS) $(LDFLAGS) -Wl,--verbose 2>&1
> +
> +$(obj)dt.o: $(DT_BIN)
> +	# We want the output format and arch.
> +	# We also hope to win a prize for ugliest Makefile / shell interaction
> +	# We look in the LDSCRIPT first.
> +	# Then try the linker which should give us the answer.
> +	# Then check it worked.
> +	oformat=`$(call process_lds,cat $(LDSCRIPT),FORMAT)` ;\
> +	oarch=`$(call process_lds,cat $(LDSCRIPT),ARCH)` ;\
> +	\
> +	[ -z $${oformat} ] && \
> +		oformat=`$(call process_lds,$(GET_LDS),FORMAT)` ;\
> +	[ -z $${oarch} ] && \
> +		oarch=`$(call process_lds,$(GET_LDS),ARCH)` ;\
> +	\
> +	[ -z $${oformat} ] && \
> +		echo "Cannot read OUTPUT_FORMAT from lds file $(LDSCRIPT)" && \
> +		exit 1 || true ;\
> +	[ -z $${oarch} ] && \
> +		echo "Cannot read OUTPUT_ARCH from lds file $(LDSCRIPT)" && \
> +		exit 1 || true ;\
> +	\
> +	cd $(dir ${DT_BIN}) && \
> +	$(OBJCOPY) -I binary -O $${oformat} -B $${oarch} \
> +		$(notdir ${DT_BIN}) $@
> +	rm $(DT_BIN)

Instead of all that, can't you just run a trivial script to generate a .c
file containing the data from DTB_BIN, and then use the compiler to compile
that, i.e. spit out something like:

const unsigned char dtb[] = {
  0xaa, 0x55, ......
};

That'd certainly drastically simplify the makefile, although waste a little
more time and temp disk space.
Simon Glass - Oct. 13, 2011, 9:22 p.m.
Hi Stephen,

On Thu, Oct 13, 2011 at 2:13 PM, Stephen Warren <swarren@nvidia.com> wrote:
> Simon Glass wrote at Tuesday, October 11, 2011 4:26 PM:
>> This new option allows U-Boot to embed a binary device tree into its image
>> to allow run-time control of peripherals. This device tree is for U-Boot's
>> own use and is not necessarily the same one as is passed to the kernel.
> ...
>> diff --git a/dts/Makefile b/dts/Makefile
> ...
>> +$(DT_BIN): $(TOPDIR)/board/$(VENDOR)/dts/$(DEVICE_TREE).dts
>> +     cat $< | $(CPP) -P $(DTS_CPPFLAGS) - >$@.tmp
>
> Couldn't that just be:
>
>        $(CPP) -P $(DTS_CPPFLAGS) $< >$@.tmp
>
>> +     $(DTC) -R 4 -p 0x1000 -O dtb -o ${DT_BIN} $@.tmp
>> +     rm $@.tmp

I did have that originally, but got this warning:

armv7a-cros-linux-gnueabi-gcc.real: warning:
/home/sjg/trunk/src/third_party/u-boot/files/board/nvidia/dts/seaboard.dts:
linker input file unused because linking not done

so I fell back to doing as I have done. I think it might be because
gcc normally assumes that anything it cannot understand must be a link
script.

Regards,
Simon

>
> --
> nvpublic
>
>
Simon Glass - Oct. 13, 2011, 9:25 p.m.
Hi Stephen,

On Thu, Oct 13, 2011 at 2:21 PM, Stephen Warren <swarren@nvidia.com> wrote:
> Simon Glass wrote at Tuesday, October 11, 2011 4:26 PM:
>> This new option allows U-Boot to embed a binary device tree into its image
>> to allow run-time control of peripherals. This device tree is for U-Boot's
>> own use and is not necessarily the same one as is passed to the kernel.
>>
>> The device tree compiler output should be placed in the $(obj)
>> rooted tree. Since $(OBJCOPY) insists on adding the path to the
>> generated symbol names, to ensure consistency it should be
>> invoked from the directory where the .dtb file is located and
>> given the input file name without the path.
> ...
>> +process_lds = \
>> +     $(1) | sed -r -n 's/^OUTPUT_$(2)[ ("]*([^")]*).*/\1/p'
>> +
>> +# Run the compiler and get the link script from the linker
>> +GET_LDS = $(CC) $(CFLAGS) $(LDFLAGS) -Wl,--verbose 2>&1
>> +
>> +$(obj)dt.o: $(DT_BIN)
>> +     # We want the output format and arch.
>> +     # We also hope to win a prize for ugliest Makefile / shell interaction
>> +     # We look in the LDSCRIPT first.
>> +     # Then try the linker which should give us the answer.
>> +     # Then check it worked.
>> +     oformat=`$(call process_lds,cat $(LDSCRIPT),FORMAT)` ;\
>> +     oarch=`$(call process_lds,cat $(LDSCRIPT),ARCH)` ;\
>> +     \
>> +     [ -z $${oformat} ] && \
>> +             oformat=`$(call process_lds,$(GET_LDS),FORMAT)` ;\
>> +     [ -z $${oarch} ] && \
>> +             oarch=`$(call process_lds,$(GET_LDS),ARCH)` ;\
>> +     \
>> +     [ -z $${oformat} ] && \
>> +             echo "Cannot read OUTPUT_FORMAT from lds file $(LDSCRIPT)" && \
>> +             exit 1 || true ;\
>> +     [ -z $${oarch} ] && \
>> +             echo "Cannot read OUTPUT_ARCH from lds file $(LDSCRIPT)" && \
>> +             exit 1 || true ;\
>> +     \
>> +     cd $(dir ${DT_BIN}) && \
>> +     $(OBJCOPY) -I binary -O $${oformat} -B $${oarch} \
>> +             $(notdir ${DT_BIN}) $@
>> +     rm $(DT_BIN)
>
> Instead of all that, can't you just run a trivial script to generate a .c
> file containing the data from DTB_BIN, and then use the compiler to compile
> that, i.e. spit out something like:
>
> const unsigned char dtb[] = {
>  0xaa, 0x55, ......
> };
>
> That'd certainly drastically simplify the makefile, although waste a little
> more time and temp disk space.

What, and withdraw my Makefile contest entry? :-)

I feel that objcopy is designed to do exactly this, and generating C
code is a roundabout way of producing an object file with data in it.
The difficulty of finding out the output format/architecture is
something we might clean up in U-Boot generally at some point (e.g.
figure it out as part of the original 'make ..._config') in which case
this would all go away.

Thoughts?

Regards,
Simon

>
> --
> nvpublic
>
>
Stephen Warren - Oct. 13, 2011, 9:50 p.m.
Simon Glass wrote at Thursday, October 13, 2011 3:25 PM:
> Hi Stephen,
> 
> On Thu, Oct 13, 2011 at 2:21 PM, Stephen Warren <swarren@nvidia.com> wrote:
> > Simon Glass wrote at Tuesday, October 11, 2011 4:26 PM:
> >> This new option allows U-Boot to embed a binary device tree into its image
> >> to allow run-time control of peripherals. This device tree is for U-Boot's
> >> own use and is not necessarily the same one as is passed to the kernel.
> >>
> >> The device tree compiler output should be placed in the $(obj)
> >> rooted tree. Since $(OBJCOPY) insists on adding the path to the
> >> generated symbol names, to ensure consistency it should be
> >> invoked from the directory where the .dtb file is located and
> >> given the input file name without the path.
> > ...
> >> +process_lds = \
> >> +     $(1) | sed -r -n 's/^OUTPUT_$(2)[ ("]*([^")]*).*/\1/p'
> >> +
> >> +# Run the compiler and get the link script from the linker
> >> +GET_LDS = $(CC) $(CFLAGS) $(LDFLAGS) -Wl,--verbose 2>&1
> >> +
> >> +$(obj)dt.o: $(DT_BIN)
> >> +     # We want the output format and arch.
> >> +     # We also hope to win a prize for ugliest Makefile / shell interaction
> >> +     # We look in the LDSCRIPT first.
> >> +     # Then try the linker which should give us the answer.
> >> +     # Then check it worked.
> >> +     oformat=`$(call process_lds,cat $(LDSCRIPT),FORMAT)` ;\
> >> +     oarch=`$(call process_lds,cat $(LDSCRIPT),ARCH)` ;\
> >> +     \
> >> +     [ -z $${oformat} ] && \
> >> +             oformat=`$(call process_lds,$(GET_LDS),FORMAT)` ;\
> >> +     [ -z $${oarch} ] && \
> >> +             oarch=`$(call process_lds,$(GET_LDS),ARCH)` ;\
> >> +     \
> >> +     [ -z $${oformat} ] && \
> >> +             echo "Cannot read OUTPUT_FORMAT from lds file $(LDSCRIPT)" && \
> >> +             exit 1 || true ;\
> >> +     [ -z $${oarch} ] && \
> >> +             echo "Cannot read OUTPUT_ARCH from lds file $(LDSCRIPT)" && \
> >> +             exit 1 || true ;\
> >> +     \
> >> +     cd $(dir ${DT_BIN}) && \
> >> +     $(OBJCOPY) -I binary -O $${oformat} -B $${oarch} \
> >> +             $(notdir ${DT_BIN}) $@
> >> +     rm $(DT_BIN)
> >
> > Instead of all that, can't you just run a trivial script to generate a .c
> > file containing the data from DTB_BIN, and then use the compiler to compile
> > that, i.e. spit out something like:
> >
> > const unsigned char dtb[] = {
> >  0xaa, 0x55, ......
> > };
> >
> > That'd certainly drastically simplify the makefile, although waste a little
> > more time and temp disk space.
> 
> What, and withdraw my Makefile contest entry? :-)

:-)

> I feel that objcopy is designed to do exactly this, and generating C
> code is a roundabout way of producing an object file with data in it.
> The difficulty of finding out the output format/architecture is
> something we might clean up in U-Boot generally at some point (e.g.
> figure it out as part of the original 'make ..._config') in which case
> this would all go away.
> 
> Thoughts?

Looking some more, dtc has option "-O asm" which writes directly to a text
file that can be assembled; there'd be no extra temp files or conversions
if you used that.
Mike Frysinger - Oct. 13, 2011, 10:58 p.m.
On Tuesday 11 October 2011 18:26:07 Simon Glass wrote:
> --- /dev/null
> +++ b/dts/Makefile
>
> +clean:
> +	rm -f $(OBJS) $(LIB)
> +	rm -f $(DT_BIN)
> +
> +distclean:	clean

i don't think this actually gets used, so punt it
-mike
Simon Glass - Oct. 15, 2011, 5:21 a.m.
Hi Stephen,

On Thu, Oct 13, 2011 at 2:50 PM, Stephen Warren <swarren@nvidia.com> wrote:
> Simon Glass wrote at Thursday, October 13, 2011 3:25 PM:
>> Hi Stephen,
>>
>> On Thu, Oct 13, 2011 at 2:21 PM, Stephen Warren <swarren@nvidia.com> wrote:
>> > Simon Glass wrote at Tuesday, October 11, 2011 4:26 PM:
>> >> This new option allows U-Boot to embed a binary device tree into its image
>> >> to allow run-time control of peripherals. This device tree is for U-Boot's
>> >> own use and is not necessarily the same one as is passed to the kernel.
>> >>
>> >> The device tree compiler output should be placed in the $(obj)
>> >> rooted tree. Since $(OBJCOPY) insists on adding the path to the
>> >> generated symbol names, to ensure consistency it should be
>> >> invoked from the directory where the .dtb file is located and
>> >> given the input file name without the path.
>> > ...
>> >> +process_lds = \
>> >> +     $(1) | sed -r -n 's/^OUTPUT_$(2)[ ("]*([^")]*).*/\1/p'
>> >> +
>> >> +# Run the compiler and get the link script from the linker
>> >> +GET_LDS = $(CC) $(CFLAGS) $(LDFLAGS) -Wl,--verbose 2>&1
>> >> +
>> >> +$(obj)dt.o: $(DT_BIN)
>> >> +     # We want the output format and arch.
>> >> +     # We also hope to win a prize for ugliest Makefile / shell interaction
>> >> +     # We look in the LDSCRIPT first.
>> >> +     # Then try the linker which should give us the answer.
>> >> +     # Then check it worked.
>> >> +     oformat=`$(call process_lds,cat $(LDSCRIPT),FORMAT)` ;\
>> >> +     oarch=`$(call process_lds,cat $(LDSCRIPT),ARCH)` ;\
>> >> +     \
>> >> +     [ -z $${oformat} ] && \
>> >> +             oformat=`$(call process_lds,$(GET_LDS),FORMAT)` ;\
>> >> +     [ -z $${oarch} ] && \
>> >> +             oarch=`$(call process_lds,$(GET_LDS),ARCH)` ;\
>> >> +     \
>> >> +     [ -z $${oformat} ] && \
>> >> +             echo "Cannot read OUTPUT_FORMAT from lds file $(LDSCRIPT)" && \
>> >> +             exit 1 || true ;\
>> >> +     [ -z $${oarch} ] && \
>> >> +             echo "Cannot read OUTPUT_ARCH from lds file $(LDSCRIPT)" && \
>> >> +             exit 1 || true ;\
>> >> +     \
>> >> +     cd $(dir ${DT_BIN}) && \
>> >> +     $(OBJCOPY) -I binary -O $${oformat} -B $${oarch} \
>> >> +             $(notdir ${DT_BIN}) $@
>> >> +     rm $(DT_BIN)
>> >
>> > Instead of all that, can't you just run a trivial script to generate a .c
>> > file containing the data from DTB_BIN, and then use the compiler to compile
>> > that, i.e. spit out something like:
>> >
>> > const unsigned char dtb[] = {
>> >  0xaa, 0x55, ......
>> > };
>> >
>> > That'd certainly drastically simplify the makefile, although waste a little
>> > more time and temp disk space.
>>
>> What, and withdraw my Makefile contest entry? :-)
>
> :-)
>
>> I feel that objcopy is designed to do exactly this, and generating C
>> code is a roundabout way of producing an object file with data in it.
>> The difficulty of finding out the output format/architecture is
>> something we might clean up in U-Boot generally at some point (e.g.
>> figure it out as part of the original 'make ..._config') in which case
>> this would all go away.
>>
>> Thoughts?
>
> Looking some more, dtc has option "-O asm" which writes directly to a text
> file that can be assembled; there'd be no extra temp files or conversions
> if you used that.

Yes! That's much better - I will use that. I think I should still
create the temp files just so that people can see what went wrong with
a failed build. For example, if there is an error in the device tree
file it is nice to see the exact file that was compiled, including
preprocessing.

But it gets rid of the architecture stuff. I do feel that objcopy is
there partly to support putting binary bobs into object files, but the
reality is that it is just too ugly.

Thanks very much for looking into this and for the suggestion.

Regards,
Simon

>
> --
> nvpublic
>
>
Grant Likely - Oct. 15, 2011, 5:46 a.m.
On Thu, Oct 13, 2011 at 3:50 PM, Stephen Warren <swarren@nvidia.com> wrote:
> Simon Glass wrote at Thursday, October 13, 2011 3:25 PM:
>> Hi Stephen,
>>
>> On Thu, Oct 13, 2011 at 2:21 PM, Stephen Warren <swarren@nvidia.com> wrote:
>> > Simon Glass wrote at Tuesday, October 11, 2011 4:26 PM:
>> >> This new option allows U-Boot to embed a binary device tree into its image
>> >> to allow run-time control of peripherals. This device tree is for U-Boot's
>> >> own use and is not necessarily the same one as is passed to the kernel.
>> >>
>> >> The device tree compiler output should be placed in the $(obj)
>> >> rooted tree. Since $(OBJCOPY) insists on adding the path to the
>> >> generated symbol names, to ensure consistency it should be
>> >> invoked from the directory where the .dtb file is located and
>> >> given the input file name without the path.
>> > ...
>> >> +process_lds = \
>> >> +     $(1) | sed -r -n 's/^OUTPUT_$(2)[ ("]*([^")]*).*/\1/p'
>> >> +
>> >> +# Run the compiler and get the link script from the linker
>> >> +GET_LDS = $(CC) $(CFLAGS) $(LDFLAGS) -Wl,--verbose 2>&1
>> >> +
>> >> +$(obj)dt.o: $(DT_BIN)
>> >> +     # We want the output format and arch.
>> >> +     # We also hope to win a prize for ugliest Makefile / shell interaction
>> >> +     # We look in the LDSCRIPT first.
>> >> +     # Then try the linker which should give us the answer.
>> >> +     # Then check it worked.
>> >> +     oformat=`$(call process_lds,cat $(LDSCRIPT),FORMAT)` ;\
>> >> +     oarch=`$(call process_lds,cat $(LDSCRIPT),ARCH)` ;\
>> >> +     \
>> >> +     [ -z $${oformat} ] && \
>> >> +             oformat=`$(call process_lds,$(GET_LDS),FORMAT)` ;\
>> >> +     [ -z $${oarch} ] && \
>> >> +             oarch=`$(call process_lds,$(GET_LDS),ARCH)` ;\
>> >> +     \
>> >> +     [ -z $${oformat} ] && \
>> >> +             echo "Cannot read OUTPUT_FORMAT from lds file $(LDSCRIPT)" && \
>> >> +             exit 1 || true ;\
>> >> +     [ -z $${oarch} ] && \
>> >> +             echo "Cannot read OUTPUT_ARCH from lds file $(LDSCRIPT)" && \
>> >> +             exit 1 || true ;\
>> >> +     \
>> >> +     cd $(dir ${DT_BIN}) && \
>> >> +     $(OBJCOPY) -I binary -O $${oformat} -B $${oarch} \
>> >> +             $(notdir ${DT_BIN}) $@
>> >> +     rm $(DT_BIN)
>> >
>> > Instead of all that, can't you just run a trivial script to generate a .c
>> > file containing the data from DTB_BIN, and then use the compiler to compile
>> > that, i.e. spit out something like:
>> >
>> > const unsigned char dtb[] = {
>> >  0xaa, 0x55, ......
>> > };
>> >
>> > That'd certainly drastically simplify the makefile, although waste a little
>> > more time and temp disk space.
>>
>> What, and withdraw my Makefile contest entry? :-)
>
> :-)
>
>> I feel that objcopy is designed to do exactly this, and generating C
>> code is a roundabout way of producing an object file with data in it.
>> The difficulty of finding out the output format/architecture is
>> something we might clean up in U-Boot generally at some point (e.g.
>> figure it out as part of the original 'make ..._config') in which case
>> this would all go away.
>>
>> Thoughts?
>
> Looking some more, dtc has option "-O asm" which writes directly to a text
> file that can be assembled; there'd be no extra temp files or conversions
> if you used that.

I recommend *not* using the asm output option.  It's not nearly as
well tested and it is likely to have some big-endian-isms in it that
don't work well.  I prefer the objcopy approach myself.  That's what
it is for.

g.
Simon Glass - Oct. 15, 2011, 2:51 p.m.
Hi Grant,

On Fri, Oct 14, 2011 at 10:46 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> On Thu, Oct 13, 2011 at 3:50 PM, Stephen Warren <swarren@nvidia.com> wrote:
>> Simon Glass wrote at Thursday, October 13, 2011 3:25 PM:
>>> Hi Stephen,
>>>
>>> On Thu, Oct 13, 2011 at 2:21 PM, Stephen Warren <swarren@nvidia.com> wrote:
>>> > Simon Glass wrote at Tuesday, October 11, 2011 4:26 PM:
>>> >> This new option allows U-Boot to embed a binary device tree into its image
>>> >> to allow run-time control of peripherals. This device tree is for U-Boot's
>>> >> own use and is not necessarily the same one as is passed to the kernel.
>>> >>
>>> >> The device tree compiler output should be placed in the $(obj)
>>> >> rooted tree. Since $(OBJCOPY) insists on adding the path to the
>>> >> generated symbol names, to ensure consistency it should be
>>> >> invoked from the directory where the .dtb file is located and
>>> >> given the input file name without the path.
>>> > ...
>>> >> +process_lds = \
>>> >> +     $(1) | sed -r -n 's/^OUTPUT_$(2)[ ("]*([^")]*).*/\1/p'
>>> >> +
>>> >> +# Run the compiler and get the link script from the linker
>>> >> +GET_LDS = $(CC) $(CFLAGS) $(LDFLAGS) -Wl,--verbose 2>&1
>>> >> +
>>> >> +$(obj)dt.o: $(DT_BIN)
>>> >> +     # We want the output format and arch.
>>> >> +     # We also hope to win a prize for ugliest Makefile / shell interaction
>>> >> +     # We look in the LDSCRIPT first.
>>> >> +     # Then try the linker which should give us the answer.
>>> >> +     # Then check it worked.
>>> >> +     oformat=`$(call process_lds,cat $(LDSCRIPT),FORMAT)` ;\
>>> >> +     oarch=`$(call process_lds,cat $(LDSCRIPT),ARCH)` ;\
>>> >> +     \
>>> >> +     [ -z $${oformat} ] && \
>>> >> +             oformat=`$(call process_lds,$(GET_LDS),FORMAT)` ;\
>>> >> +     [ -z $${oarch} ] && \
>>> >> +             oarch=`$(call process_lds,$(GET_LDS),ARCH)` ;\
>>> >> +     \
>>> >> +     [ -z $${oformat} ] && \
>>> >> +             echo "Cannot read OUTPUT_FORMAT from lds file $(LDSCRIPT)" && \
>>> >> +             exit 1 || true ;\
>>> >> +     [ -z $${oarch} ] && \
>>> >> +             echo "Cannot read OUTPUT_ARCH from lds file $(LDSCRIPT)" && \
>>> >> +             exit 1 || true ;\
>>> >> +     \
>>> >> +     cd $(dir ${DT_BIN}) && \
>>> >> +     $(OBJCOPY) -I binary -O $${oformat} -B $${oarch} \
>>> >> +             $(notdir ${DT_BIN}) $@
>>> >> +     rm $(DT_BIN)
>>> >
>>> > Instead of all that, can't you just run a trivial script to generate a .c
>>> > file containing the data from DTB_BIN, and then use the compiler to compile
>>> > that, i.e. spit out something like:
>>> >
>>> > const unsigned char dtb[] = {
>>> >  0xaa, 0x55, ......
>>> > };
>>> >
>>> > That'd certainly drastically simplify the makefile, although waste a little
>>> > more time and temp disk space.
>>>
>>> What, and withdraw my Makefile contest entry? :-)
>>
>> :-)
>>
>>> I feel that objcopy is designed to do exactly this, and generating C
>>> code is a roundabout way of producing an object file with data in it.
>>> The difficulty of finding out the output format/architecture is
>>> something we might clean up in U-Boot generally at some point (e.g.
>>> figure it out as part of the original 'make ..._config') in which case
>>> this would all go away.
>>>
>>> Thoughts?
>>
>> Looking some more, dtc has option "-O asm" which writes directly to a text
>> file that can be assembled; there'd be no extra temp files or conversions
>> if you used that.
>
> I recommend *not* using the asm output option.  It's not nearly as
> well tested and it is likely to have some big-endian-isms in it that
> don't work well.  I prefer the objcopy approach myself.  That's what
> it is for.

Oh dear that sounds bad. The difficultly is in figuring out the
arguments to objcopy (architecture and oformat). But we do need it to
work reliably, so I will move back to the original approach for now.

Regards,
Simon

>
> g.
>

Patch

diff --git a/Makefile b/Makefile
index 5db2e0e..52a6348 100644
--- a/Makefile
+++ b/Makefile
@@ -224,6 +224,9 @@  endif
 ifeq ($(CPU),ixp)
 LIBS += arch/arm/cpu/ixp/npe/libnpe.o
 endif
+ifeq ($(CONFIG_OF_EMBED),y)
+LIBS += dts/libdts.o
+endif
 LIBS += arch/$(ARCH)/lib/lib$(ARCH).o
 LIBS += fs/cramfs/libcramfs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o \
 	fs/reiserfs/libreiserfs.o fs/ext2/libext2fs.o fs/yaffs2/libyaffs2.o \
@@ -962,6 +965,7 @@  clobber:	clean
 	@rm -f $(obj)u-boot.kwb
 	@rm -f $(obj)u-boot.imx
 	@rm -f $(obj)u-boot.ubl
+	@rm -f $(obj)u-boot.dtb
 	@rm -f $(obj)tools/{env/crc32.c,inca-swap-bytes}
 	@rm -f $(obj)arch/powerpc/cpu/mpc824x/bedbug_603e.c
 	@rm -fr $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
diff --git a/README b/README
index 1175960..8678d78 100644
--- a/README
+++ b/README
@@ -818,8 +818,15 @@  The following options need to be configured:
 		experimental and only available on a few boards. The device
 		tree is available in the global data as gd->blob.
 
-		U-Boot needs to get its device tree from somewhere. This will
-		be enabled in a future patch.
+		U-Boot needs to get its device tree from somewhere. At present
+		the only way is to embed it in the image with CONFIG_OF_EMBED.
+
+		CONFIG_OF_EMBED
+		If this variable is defined, U-Boot will embed a device tree
+		binary in its image. This device tree file should be in the
+		board directory and called <soc>-<board>.dts. The binary file
+		is then picked up in board_init_f() and made available through
+		the global data structure as gd->blob.
 
 - Watchdog:
 		CONFIG_WATCHDOG
diff --git a/config.mk b/config.mk
index e2b440d..6e61eb6 100644
--- a/config.mk
+++ b/config.mk
@@ -124,6 +124,7 @@  STRIP	= $(CROSS_COMPILE)strip
 OBJCOPY = $(CROSS_COMPILE)objcopy
 OBJDUMP = $(CROSS_COMPILE)objdump
 RANLIB	= $(CROSS_COMPILE)RANLIB
+DTC	= dtc
 
 #########################################################################
 
diff --git a/dts/Makefile b/dts/Makefile
new file mode 100644
index 0000000..06b7603
--- /dev/null
+++ b/dts/Makefile
@@ -0,0 +1,109 @@ 
+#
+# Copyright (c) 2011 The Chromium OS Authors.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundatio; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+# This Makefile builds the internal U-Boot fdt if CONFIG_OF_CONTROL is
+# enabled. See doc/README.fdt-control for more details.
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)libdts.o
+
+$(if $(CONFIG_DEFAULT_DEVICE_TREE),,\
+$(error Please define CONFIG_DEFAULT_DEVICE_TREE in your board header file))
+DEVICE_TREE = $(subst ",,$(CONFIG_DEFAULT_DEVICE_TREE))
+
+$(if $(CONFIG_ARCH_DEVICE_TREE),,\
+$(error Your architecture does not have device tree support enabled. \
+Please define CONFIG_ARCH_DEVICE_TREE))
+
+# We preprocess the device tree file provide a useful define
+DTS_CPPFLAGS := -DARCH_CPU_DTS=\"../arch/$(ARCH)/dts/$(CONFIG_ARCH_DEVICE_TREE).dtsi\"
+
+all:	$(obj).depend $(LIB)
+
+# Use a constant name for this so we can access it from C code.
+# objcopy doesn't seem to allow us to set the symbol name independently of
+# the filename.
+DT_BIN	:= $(obj)dt.dtb
+
+$(DT_BIN): $(TOPDIR)/board/$(VENDOR)/dts/$(DEVICE_TREE).dts
+	cat $< | $(CPP) -P $(DTS_CPPFLAGS) - >$@.tmp
+	$(DTC) -R 4 -p 0x1000 -O dtb -o ${DT_BIN} $@.tmp
+	rm $@.tmp
+
+process_lds = \
+	$(1) | sed -r -n 's/^OUTPUT_$(2)[ ("]*([^")]*).*/\1/p'
+
+# Run the compiler and get the link script from the linker
+GET_LDS = $(CC) $(CFLAGS) $(LDFLAGS) -Wl,--verbose 2>&1
+
+$(obj)dt.o: $(DT_BIN)
+	# We want the output format and arch.
+	# We also hope to win a prize for ugliest Makefile / shell interaction
+	# We look in the LDSCRIPT first.
+	# Then try the linker which should give us the answer.
+	# Then check it worked.
+	oformat=`$(call process_lds,cat $(LDSCRIPT),FORMAT)` ;\
+	oarch=`$(call process_lds,cat $(LDSCRIPT),ARCH)` ;\
+	\
+	[ -z $${oformat} ] && \
+		oformat=`$(call process_lds,$(GET_LDS),FORMAT)` ;\
+	[ -z $${oarch} ] && \
+		oarch=`$(call process_lds,$(GET_LDS),ARCH)` ;\
+	\
+	[ -z $${oformat} ] && \
+		echo "Cannot read OUTPUT_FORMAT from lds file $(LDSCRIPT)" && \
+		exit 1 || true ;\
+	[ -z $${oarch} ] && \
+		echo "Cannot read OUTPUT_ARCH from lds file $(LDSCRIPT)" && \
+		exit 1 || true ;\
+	\
+	cd $(dir ${DT_BIN}) && \
+	$(OBJCOPY) -I binary -O $${oformat} -B $${oarch} \
+		$(notdir ${DT_BIN}) $@
+	rm $(DT_BIN)
+
+OBJS-$(CONFIG_OF_EMBED)	:= dt.o
+
+COBJS	:= $(OBJS-y)
+
+OBJS	:= $(addprefix $(obj),$(COBJS))
+
+binary:	$(DT_BIN)
+
+$(LIB):	$(OBJS) $(DTB)
+	$(call cmd_link_o_target, $(OBJS))
+
+clean:
+	rm -f $(OBJS) $(LIB)
+	rm -f $(DT_BIN)
+
+distclean:	clean
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/include/common.h b/include/common.h
index eb19a44..1feeaf4 100644
--- a/include/common.h
+++ b/include/common.h
@@ -270,6 +270,7 @@  int	checkdram     (void);
 int	last_stage_init(void);
 extern ulong monitor_flash_len;
 int mac_read_from_eeprom(void);
+extern u8 _binary_dt_dtb_start[];	/* embedded device tree blob */
 
 /* common/flash.c */
 void flash_perror (int);