[RFC 2/2] ARM:boot:device tree: Merge specific atags into the device tree

Nicolas Pitre nico at fluxnic.net
Thu Feb 3 23:44:31 EST 2011


On Wed, 26 Jan 2011, John Bonesio wrote:

> This patch is to merge in key atags into the appended device tree.  An appended
> device tree is where the zImage has a dtb binary appended at the end of it. The
> boot code looks for an appended device tree, then looks for a few key atags
> passed in by the bootloader.
> 
> The bootargs and memory size settings, if they exist, override existing values
> in the appended device tree. If these values don't currently exist in the
> appended device tree, they are added.
> 
> Signed-off-by: John Bonesio <bones at secretlab.ca>
> Acked-by: Grant Likely <grant.likely at secretlab.ca>

This is just for testing/evaluation purpose and not intended to be 
merged upstream at some point, right?

> ---
> 
>  arch/arm/boot/compressed/Makefile |   31 +++++++++++++++++---
>  arch/arm/boot/compressed/atags.c  |   50 ++++++++++++++++++++++++++++++++
>  arch/arm/boot/compressed/head.S   |    7 ++++
>  arch/arm/boot/compressed/misc.c   |   58 ++++++++++++++++++++++++++++++++++++-
>  4 files changed, 139 insertions(+), 7 deletions(-)
>  create mode 100644 arch/arm/boot/compressed/atags.c
> 
> diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
> index 0a8f748..7978a39 100644
> --- a/arch/arm/boot/compressed/Makefile
> +++ b/arch/arm/boot/compressed/Makefile
> @@ -49,6 +49,10 @@ ifeq ($(CONFIG_ARCH_SHMOBILE),y)
>  OBJS		+= head-shmobile.o
>  endif
>  
> +ifeq ($(CONFIG_ARM_APPENDED_DTB),y)
> +OBJS		+= atags.o libfdt.a 
> +endif
> +
>  #
>  # We now have a PIC decompressor implementation.  Decompressors running
>  # from RAM should not define ZTEXTADDR.  Decompressors running directly
> @@ -80,7 +84,9 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS)
>  KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
>  endif
>  
> -EXTRA_CFLAGS  := -fpic -fno-builtin
> +fdttree      := $(srctree)/scripts/dtc/libfdt
> +
> +EXTRA_CFLAGS  := -fpic -fno-builtin -I$(fdttree) -I$(obj)
>  EXTRA_AFLAGS  := -Wa,-march=all
>  
>  # Supply ZRELADDR to the decompressor via a linker symbol.
> @@ -100,13 +106,28 @@ LDFLAGS_vmlinux += -X
>  LDFLAGS_vmlinux += -T
>  
>  # For __aeabi_uidivmod
> -lib1funcs = $(obj)/lib1funcs.o
> +libfuncs = $(obj)/lib1funcs.o
>  
> -$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE
> -	$(call cmd,shipped)
> +ifeq ($(CONFIG_ARM_APPENDED_DTB),y)
> +# For memchr, memmove, etc
> +libfuncs += $(obj)/memchr.o $(obj)/strchr.o $(obj)/memmove.o $(obj)/memzero.o
> +endif
> +
> +
> +libfdtheader := $(fdttree)/fdt.h $(fdttree)/libfdt.h $(fdttree)/libfdt_internal.h
> +libfdtobj    := $(obj)/fdt.o $(obj)/fdt_ro.o $(obj)/fdt_wip.o $(obj)/fdt_sw.o $(obj)/fdt_rw.o $(obj)/fdt_strerror.o
> +
> +$(libfdtobj): $(obj)/%.o: $(srctree)/scripts/dtc/libfdt/%.c $(libfdtheader)
> +	$(call cmd_cc_o_c)
> +
> +$(obj)/libfdt.a: $(libfdtobj)
> +	$(AR) rcs $@ $^
> +
> +$(libfuncs): $(obj)/%.o: $(srctree)/arch/$(SRCARCH)/lib/%.S
> +	$(call cmd_as_o_S)
>  
>  $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
> -	 	$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
> +	 	$(addprefix $(obj)/, $(OBJS)) $(libfuncs) FORCE
>  	$(call if_changed,ld)
>  	@:
>  
> diff --git a/arch/arm/boot/compressed/atags.c b/arch/arm/boot/compressed/atags.c
> new file mode 100644
> index 0000000..e37d8de
> --- /dev/null
> +++ b/arch/arm/boot/compressed/atags.c
> @@ -0,0 +1,50 @@
> +#include <stddef.h>
> +#include <asm/byteorder.h>
> +#include <asm/setup.h>
> +#include <fdt.h>
> +#include <libfdt.h>
> +
> +
> +int dt_setprop(void *fdt, const char *node_path, const char *property,
> +               uint32_t *val_array, int size)
> +{
> +	int offset;
> +
> +	offset = fdt_path_offset(fdt, node_path);
> +	if (offset < 0)
> +		return offset;
> +
> +	return fdt_setprop(fdt, offset, property, val_array, size);
> +}
> +
> +int dt_setprop_string(void *fdt, const char *node_path,
> +                      const char *property, const char *string)
> +{
> +	int offset;
> +		
> +	offset = fdt_path_offset(fdt, node_path);
> +	if (offset < 0)
> +		return offset;
> +			
> +	return fdt_setprop_string(fdt, offset, property, string);
> +}
> +
> +void dt_merge_atags(void *dt,  void *ataglist)
> +{
> +	struct tag *atag = ataglist;
> +	uint32_t mem_reg_property[2];
> +
> +	while (atag && atag->hdr.tag != 0) {
> +		if (atag->hdr.tag == ATAG_CMDLINE) {
> +			dt_setprop_string(dt, "/chosen", "bootargs",
> +			                  atag->u.cmdline.cmdline);
> +		} else if (atag->hdr.tag == ATAG_MEM) {
> +			mem_reg_property[0] = cpu_to_fdt32(atag->u.mem.start);
> +			mem_reg_property[1] = cpu_to_fdt32(atag->u.mem.size);
> +			dt_setprop(dt, "/memory", "reg", mem_reg_property,
> +			           sizeof(mem_reg_property));
> +		}
> +		atag = tag_next(atag);
> +	}
> +}
> +
> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
> index db860b3..09e659d 100644
> --- a/arch/arm/boot/compressed/head.S
> +++ b/arch/arm/boot/compressed/head.S
> @@ -257,6 +257,13 @@ not_relocated:
>  		cmp	r1, r9
>  		bne	keep_atags
>  
> +		/* Merge some of the atags into the device tree */
> +		push	{r2, r3, r10, r11}
> +		mov	r0, r2
> +		mov	r1, r8
> +		bl	dt_merge_atags
> +		pop	{r2, r3, r10, r11}
> +
>  		/* copy the device tree binary to 0x0 */
>  		ldr	r9, [r10, #4]	@ device tree size
>  
> diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
> index e653a6d..2d4da4c 100644
> --- a/arch/arm/boot/compressed/misc.c
> +++ b/arch/arm/boot/compressed/misc.c
> @@ -29,7 +29,7 @@ unsigned int __machine_arch_type;
>  #include <asm/unaligned.h>
>  
>  
> -static void putstr(const char *ptr);
> +void putstr(const char *ptr);
>  extern void error(char *x);
>  
>  #include <mach/uncompress.h>
> @@ -100,7 +100,7 @@ static void icedcc_putc(int ch)
>  #define putc(ch)	icedcc_putc(ch)
>  #endif
>  
> -static void putstr(const char *ptr)
> +void putstr(const char *ptr)
>  {
>  	char c;
>  
> @@ -114,6 +114,60 @@ static void putstr(const char *ptr)
>  }
>  
>  
> +#ifdef CONFIG_ARM_APPENDED_DTB
> +/**
> + * strlen - Find the length of a string
> + * @s: The string to be sized
> + */
> +size_t strlen(const char *s)
> +{
> +        const char *sc;
> +
> +        for (sc = s; *sc != '\0'; ++sc)
> +                /* nothing */;
> +        return sc - s;
> +}
> +
> +/**
> + * strcmp - Compare two strings
> + * @cs: One string
> + * @ct: Another string
> + */
> +#undef strcmp
> +int strcmp(const char *cs, const char *ct)
> +{
> +	unsigned char c1, c2;
> +
> +	while (1) {
> +		c1 = *cs++;
> +		c2 = *ct++;
> +		if (c1 != c2)
> +			return c1 < c2 ? -1 : 1;
> +		if (!c1)
> +			break;
> +	}
> +	return 0;
> +}
> +
> +/**
> + * memcmp - Compare two areas of memory
> + * @cs: One area of memory
> + * @ct: Another area of memory
> + * @count: The size of the area.
> + */
> +#undef memcmp
> +int memcmp(const void *cs, const void *ct, size_t count)
> +{
> +	const unsigned char *su1, *su2;
> +	int res = 0;
> +
> +	for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
> +		if ((res = *su1 - *su2) != 0)
> +			break;
> +	return res;
> +}
> +#endif
> +
>  void *memcpy(void *__dest, __const void *__src, size_t __n)
>  {
>  	int i = 0;
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 



More information about the linux-arm-kernel mailing list