<p><br>
On Feb 3, 2011 9:44 PM, &quot;Nicolas Pitre&quot; &lt;<a href="mailto:nico@fluxnic.net">nico@fluxnic.net</a>&gt; wrote:<br>
&gt;<br>
&gt; On Wed, 26 Jan 2011, John Bonesio wrote:<br>
&gt;<br>
&gt; &gt; This patch is to merge in key atags into the appended device tree.  An appended<br>
&gt; &gt; device tree is where the zImage has a dtb binary appended at the end of it. The<br>
&gt; &gt; boot code looks for an appended device tree, then looks for a few key atags<br>
&gt; &gt; passed in by the bootloader.<br>
&gt; &gt;<br>
&gt; &gt; The bootargs and memory size settings, if they exist, override existing values<br>
&gt; &gt; in the appended device tree. If these values don&#39;t currently exist in the<br>
&gt; &gt; appended device tree, they are added.<br>
&gt; &gt;<br>
&gt; &gt; Signed-off-by: John Bonesio &lt;<a href="mailto:bones@secretlab.ca">bones@secretlab.ca</a>&gt;<br>
&gt; &gt; Acked-by: Grant Likely &lt;<a href="mailto:grant.likely@secretlab.ca">grant.likely@secretlab.ca</a>&gt;<br>
&gt;<br>
&gt; This is just for testing/evaluation purpose and not intended to be<br>
&gt; merged upstream at some point, right?</p>
<p>Correct.</p>
<p>&gt;<br>
&gt; &gt; ---<br>
&gt; &gt;<br>
&gt; &gt;  arch/arm/boot/compressed/Makefile |   31 +++++++++++++++++---<br>
&gt; &gt;  arch/arm/boot/compressed/atags.c  |   50 ++++++++++++++++++++++++++++++++<br>
&gt; &gt;  arch/arm/boot/compressed/head.S   |    7 ++++<br>
&gt; &gt;  arch/arm/boot/compressed/misc.c   |   58 ++++++++++++++++++++++++++++++++++++-<br>
&gt; &gt;  4 files changed, 139 insertions(+), 7 deletions(-)<br>
&gt; &gt;  create mode 100644 arch/arm/boot/compressed/atags.c<br>
&gt; &gt;<br>
&gt; &gt; diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile<br>
&gt; &gt; index 0a8f748..7978a39 100644<br>
&gt; &gt; --- a/arch/arm/boot/compressed/Makefile<br>
&gt; &gt; +++ b/arch/arm/boot/compressed/Makefile<br>
&gt; &gt; @@ -49,6 +49,10 @@ ifeq ($(CONFIG_ARCH_SHMOBILE),y)<br>
&gt; &gt;  OBJS         += head-shmobile.o<br>
&gt; &gt;  endif<br>
&gt; &gt;<br>
&gt; &gt; +ifeq ($(CONFIG_ARM_APPENDED_DTB),y)<br>
&gt; &gt; +OBJS         += atags.o libfdt.a<br>
&gt; &gt; +endif<br>
&gt; &gt; +<br>
&gt; &gt;  #<br>
&gt; &gt;  # We now have a PIC decompressor implementation.  Decompressors running<br>
&gt; &gt;  # from RAM should not define ZTEXTADDR.  Decompressors running directly<br>
&gt; &gt; @@ -80,7 +84,9 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS)<br>
&gt; &gt;  KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))<br>
&gt; &gt;  endif<br>
&gt; &gt;<br>
&gt; &gt; -EXTRA_CFLAGS  := -fpic -fno-builtin<br>
&gt; &gt; +fdttree      := $(srctree)/scripts/dtc/libfdt<br>
&gt; &gt; +<br>
&gt; &gt; +EXTRA_CFLAGS  := -fpic -fno-builtin -I$(fdttree) -I$(obj)<br>
&gt; &gt;  EXTRA_AFLAGS  := -Wa,-march=all<br>
&gt; &gt;<br>
&gt; &gt;  # Supply ZRELADDR to the decompressor via a linker symbol.<br>
&gt; &gt; @@ -100,13 +106,28 @@ LDFLAGS_vmlinux += -X<br>
&gt; &gt;  LDFLAGS_vmlinux += -T<br>
&gt; &gt;<br>
&gt; &gt;  # For __aeabi_uidivmod<br>
&gt; &gt; -lib1funcs = $(obj)/lib1funcs.o<br>
&gt; &gt; +libfuncs = $(obj)/lib1funcs.o<br>
&gt; &gt;<br>
&gt; &gt; -$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE<br>
&gt; &gt; -     $(call cmd,shipped)<br>
&gt; &gt; +ifeq ($(CONFIG_ARM_APPENDED_DTB),y)<br>
&gt; &gt; +# For memchr, memmove, etc<br>
&gt; &gt; +libfuncs += $(obj)/memchr.o $(obj)/strchr.o $(obj)/memmove.o $(obj)/memzero.o<br>
&gt; &gt; +endif<br>
&gt; &gt; +<br>
&gt; &gt; +<br>
&gt; &gt; +libfdtheader := $(fdttree)/fdt.h $(fdttree)/libfdt.h $(fdttree)/libfdt_internal.h<br>
&gt; &gt; +libfdtobj    := $(obj)/fdt.o $(obj)/fdt_ro.o $(obj)/fdt_wip.o $(obj)/fdt_sw.o $(obj)/fdt_rw.o $(obj)/fdt_strerror.o<br>
&gt; &gt; +<br>
&gt; &gt; +$(libfdtobj): $(obj)/%.o: $(srctree)/scripts/dtc/libfdt/%.c $(libfdtheader)<br>
&gt; &gt; +     $(call cmd_cc_o_c)<br>
&gt; &gt; +<br>
&gt; &gt; +$(obj)/libfdt.a: $(libfdtobj)<br>
&gt; &gt; +     $(AR) rcs $@ $^<br>
&gt; &gt; +<br>
&gt; &gt; +$(libfuncs): $(obj)/%.o: $(srctree)/arch/$(SRCARCH)/lib/%.S<br>
&gt; &gt; +     $(call cmd_as_o_S)<br>
&gt; &gt;<br>
&gt; &gt;  $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \<br>
&gt; &gt; -             $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE<br>
&gt; &gt; +             $(addprefix $(obj)/, $(OBJS)) $(libfuncs) FORCE<br>
&gt; &gt;       $(call if_changed,ld)<br>
&gt; &gt;       @:<br>
&gt; &gt;<br>
&gt; &gt; diff --git a/arch/arm/boot/compressed/atags.c b/arch/arm/boot/compressed/atags.c<br>
&gt; &gt; new file mode 100644<br>
&gt; &gt; index 0000000..e37d8de<br>
&gt; &gt; --- /dev/null<br>
&gt; &gt; +++ b/arch/arm/boot/compressed/atags.c<br>
&gt; &gt; @@ -0,0 +1,50 @@<br>
&gt; &gt; +#include &lt;stddef.h&gt;<br>
&gt; &gt; +#include &lt;asm/byteorder.h&gt;<br>
&gt; &gt; +#include &lt;asm/setup.h&gt;<br>
&gt; &gt; +#include &lt;fdt.h&gt;<br>
&gt; &gt; +#include &lt;libfdt.h&gt;<br>
&gt; &gt; +<br>
&gt; &gt; +<br>
&gt; &gt; +int dt_setprop(void *fdt, const char *node_path, const char *property,<br>
&gt; &gt; +               uint32_t *val_array, int size)<br>
&gt; &gt; +{<br>
&gt; &gt; +     int offset;<br>
&gt; &gt; +<br>
&gt; &gt; +     offset = fdt_path_offset(fdt, node_path);<br>
&gt; &gt; +     if (offset &lt; 0)<br>
&gt; &gt; +             return offset;<br>
&gt; &gt; +<br>
&gt; &gt; +     return fdt_setprop(fdt, offset, property, val_array, size);<br>
&gt; &gt; +}<br>
&gt; &gt; +<br>
&gt; &gt; +int dt_setprop_string(void *fdt, const char *node_path,<br>
&gt; &gt; +                      const char *property, const char *string)<br>
&gt; &gt; +{<br>
&gt; &gt; +     int offset;<br>
&gt; &gt; +<br>
&gt; &gt; +     offset = fdt_path_offset(fdt, node_path);<br>
&gt; &gt; +     if (offset &lt; 0)<br>
&gt; &gt; +             return offset;<br>
&gt; &gt; +<br>
&gt; &gt; +     return fdt_setprop_string(fdt, offset, property, string);<br>
&gt; &gt; +}<br>
&gt; &gt; +<br>
&gt; &gt; +void dt_merge_atags(void *dt,  void *ataglist)<br>
&gt; &gt; +{<br>
&gt; &gt; +     struct tag *atag = ataglist;<br>
&gt; &gt; +     uint32_t mem_reg_property[2];<br>
&gt; &gt; +<br>
&gt; &gt; +     while (atag &amp;&amp; atag-&gt;hdr.tag != 0) {<br>
&gt; &gt; +             if (atag-&gt;hdr.tag == ATAG_CMDLINE) {<br>
&gt; &gt; +                     dt_setprop_string(dt, &quot;/chosen&quot;, &quot;bootargs&quot;,<br>
&gt; &gt; +                                       atag-&gt;u.cmdline.cmdline);<br>
&gt; &gt; +             } else if (atag-&gt;hdr.tag == ATAG_MEM) {<br>
&gt; &gt; +                     mem_reg_property[0] = cpu_to_fdt32(atag-&gt;u.mem.start);<br>
&gt; &gt; +                     mem_reg_property[1] = cpu_to_fdt32(atag-&gt;u.mem.size);<br>
&gt; &gt; +                     dt_setprop(dt, &quot;/memory&quot;, &quot;reg&quot;, mem_reg_property,<br>
&gt; &gt; +                                sizeof(mem_reg_property));<br>
&gt; &gt; +             }<br>
&gt; &gt; +             atag = tag_next(atag);<br>
&gt; &gt; +     }<br>
&gt; &gt; +}<br>
&gt; &gt; +<br>
&gt; &gt; diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S<br>
&gt; &gt; index db860b3..09e659d 100644<br>
&gt; &gt; --- a/arch/arm/boot/compressed/head.S<br>
&gt; &gt; +++ b/arch/arm/boot/compressed/head.S<br>
&gt; &gt; @@ -257,6 +257,13 @@ not_relocated:<br>
&gt; &gt;               cmp     r1, r9<br>
&gt; &gt;               bne     keep_atags<br>
&gt; &gt;<br>
&gt; &gt; +             /* Merge some of the atags into the device tree */<br>
&gt; &gt; +             push    {r2, r3, r10, r11}<br>
&gt; &gt; +             mov     r0, r2<br>
&gt; &gt; +             mov     r1, r8<br>
&gt; &gt; +             bl      dt_merge_atags<br>
&gt; &gt; +             pop     {r2, r3, r10, r11}<br>
&gt; &gt; +<br>
&gt; &gt;               /* copy the device tree binary to 0x0 */<br>
&gt; &gt;               ldr     r9, [r10, #4]   @ device tree size<br>
&gt; &gt;<br>
&gt; &gt; diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c<br>
&gt; &gt; index e653a6d..2d4da4c 100644<br>
&gt; &gt; --- a/arch/arm/boot/compressed/misc.c<br>
&gt; &gt; +++ b/arch/arm/boot/compressed/misc.c<br>
&gt; &gt; @@ -29,7 +29,7 @@ unsigned int __machine_arch_type;<br>
&gt; &gt;  #include &lt;asm/unaligned.h&gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; -static void putstr(const char *ptr);<br>
&gt; &gt; +void putstr(const char *ptr);<br>
&gt; &gt;  extern void error(char *x);<br>
&gt; &gt;<br>
&gt; &gt;  #include &lt;mach/uncompress.h&gt;<br>
&gt; &gt; @@ -100,7 +100,7 @@ static void icedcc_putc(int ch)<br>
&gt; &gt;  #define putc(ch)     icedcc_putc(ch)<br>
&gt; &gt;  #endif<br>
&gt; &gt;<br>
&gt; &gt; -static void putstr(const char *ptr)<br>
&gt; &gt; +void putstr(const char *ptr)<br>
&gt; &gt;  {<br>
&gt; &gt;       char c;<br>
&gt; &gt;<br>
&gt; &gt; @@ -114,6 +114,60 @@ static void putstr(const char *ptr)<br>
&gt; &gt;  }<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; +#ifdef CONFIG_ARM_APPENDED_DTB<br>
&gt; &gt; +/**<br>
&gt; &gt; + * strlen - Find the length of a string<br>
&gt; &gt; + * @s: The string to be sized<br>
&gt; &gt; + */<br>
&gt; &gt; +size_t strlen(const char *s)<br>
&gt; &gt; +{<br>
&gt; &gt; +        const char *sc;<br>
&gt; &gt; +<br>
&gt; &gt; +        for (sc = s; *sc != &#39;\0&#39;; ++sc)<br>
&gt; &gt; +                /* nothing */;<br>
&gt; &gt; +        return sc - s;<br>
&gt; &gt; +}<br>
&gt; &gt; +<br>
&gt; &gt; +/**<br>
&gt; &gt; + * strcmp - Compare two strings<br>
&gt; &gt; + * @cs: One string<br>
&gt; &gt; + * @ct: Another string<br>
&gt; &gt; + */<br>
&gt; &gt; +#undef strcmp<br>
&gt; &gt; +int strcmp(const char *cs, const char *ct)<br>
&gt; &gt; +{<br>
&gt; &gt; +     unsigned char c1, c2;<br>
&gt; &gt; +<br>
&gt; &gt; +     while (1) {<br>
&gt; &gt; +             c1 = *cs++;<br>
&gt; &gt; +             c2 = *ct++;<br>
&gt; &gt; +             if (c1 != c2)<br>
&gt; &gt; +                     return c1 &lt; c2 ? -1 : 1;<br>
&gt; &gt; +             if (!c1)<br>
&gt; &gt; +                     break;<br>
&gt; &gt; +     }<br>
&gt; &gt; +     return 0;<br>
&gt; &gt; +}<br>
&gt; &gt; +<br>
&gt; &gt; +/**<br>
&gt; &gt; + * memcmp - Compare two areas of memory<br>
&gt; &gt; + * @cs: One area of memory<br>
&gt; &gt; + * @ct: Another area of memory<br>
&gt; &gt; + * @count: The size of the area.<br>
&gt; &gt; + */<br>
&gt; &gt; +#undef memcmp<br>
&gt; &gt; +int memcmp(const void *cs, const void *ct, size_t count)<br>
&gt; &gt; +{<br>
&gt; &gt; +     const unsigned char *su1, *su2;<br>
&gt; &gt; +     int res = 0;<br>
&gt; &gt; +<br>
&gt; &gt; +     for (su1 = cs, su2 = ct; 0 &lt; count; ++su1, ++su2, count--)<br>
&gt; &gt; +             if ((res = *su1 - *su2) != 0)<br>
&gt; &gt; +                     break;<br>
&gt; &gt; +     return res;<br>
&gt; &gt; +}<br>
&gt; &gt; +#endif<br>
&gt; &gt; +<br>
&gt; &gt;  void *memcpy(void *__dest, __const void *__src, size_t __n)<br>
&gt; &gt;  {<br>
&gt; &gt;       int i = 0;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; _______________________________________________<br>
&gt; &gt; linux-arm-kernel mailing list<br>
&gt; &gt; <a href="mailto:linux-arm-kernel@lists.infradead.org">linux-arm-kernel@lists.infradead.org</a><br>
&gt; &gt; <a href="http://lists.infradead.org/mailman/listinfo/linux-arm-kernel">http://lists.infradead.org/mailman/listinfo/linux-arm-kernel</a><br>
&gt; &gt;<br>
</p>