[PATCH 4/4] ARM:boot:device tree: Allow multiple device trees to be appended to zImage

John Bonesio bones at secretlab.ca
Mon Feb 28 18:33:56 EST 2011


This patch allows mutliple device tree binaries to be appended to zImage. A
device tree binary is selected when the 'machine_type' property in the root
node in the dtb matches the machine type passed in by the boot loader.

If the device tree binary does not have the 'machine_type' property, the device
tree is assumed to match the machine type. If no device tree binary matches,
the kernel attempts to boot with out a device tree.

Signed-off-by: John Bonesio <bones at secretlab.ca>
---

 arch/arm/boot/compressed/head.S |   30 ++++++++++++++++++++++-
 arch/arm/boot/compressed/misc.c |   51 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+), 1 deletions(-)

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index c2cdc5f..f743431 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -229,7 +229,7 @@ restart:	adr	r0, LC0
  * if there are device trees (dtb) appended to zImage, advance r10 so that the
  * dtb data will get relocated along with the kernel if necessary.
  */
-
+1:
 		ldr	r12, [r6, #0]
 		ldr	r1, =0xedfe0dd0		@ sig is 0xdoodfeed big endian
 		cmp	r12, r1
@@ -248,6 +248,7 @@ restart:	adr	r0, LC0
 
 		add	r10, r10, r12
 		add	r6, r6, r12
+		b	1b
 
 dtb_check_done:
 		adr	r1, LC0
@@ -396,11 +397,34 @@ wont_overwrite:
  *
  * if there is a device tree (dtb) appended to zImage, set up to use this dtb.
  */
+		mvn	r9, #0			@ r9 dtb search result
+		   	      			@ ... -1 = no appended dtb
+dt_search:
 		ldr	r0, [r6, #0]
 		ldr	r1, =0xedfe0dd0		@ sig is 0xdoodfeed big endian
 		cmp	r0, r1
 		bne	keep_atags
 
+		/* Get the dtb's size */
+		ldr	r5, [r6, #4]		@ device tree size
+
+		/* convert dtb size to little endian */
+		eor	r1, r5, r5, ror #16
+		bic	r1, r1, #0x00ff0000
+		mov	r5, r5, ror #8
+		eor	r5, r5, r1, lsr #8
+
+		mov	r0, r6
+		mov	r1, r7
+		bl	match_dt_machine_type
+		mov	r9, r0			@ save result
+		cmp	r0, #0
+		bne	dt_found
+
+		add	r6, r5
+		b	dt_search
+
+dt_found:
 #ifndef CONFIG_ZBOOT_ROM
 		ldr	r0, [r6, #4]
 		add	r0, r0, #MERGE_SPACE	
@@ -413,6 +437,10 @@ wont_overwrite:
 #endif
 		mov	r8, r6			@ use the appended device tree
 keep_atags:
+
+		mov	r0, r9
+		mov	r1, r7
+		bl	put_dt_match_str
 #endif
 /*
  * Set up some pointers, and start decompressing.
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index 9af05ed..f16ca6a 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -25,6 +25,8 @@ unsigned int __machine_arch_type;
 #include <linux/stddef.h>	/* for NULL */
 #include <linux/linkage.h>
 #include <asm/string.h>
+#include <fdt.h>
+#include <libfdt.h>
 
 #include <asm/unaligned.h>
 
@@ -227,6 +229,55 @@ void *memcpy(void *__dest, __const void *__src, size_t __n)
 	return __dest;
 }
 
+int match_dt_machine_type(void *fdt, unsigned int mach_type)
+{
+	int offset;
+	unsigned dt_mach_type;
+	unsigned *prop;
+	int match;
+
+	offset = fdt_path_offset(fdt, "/");
+	if (offset < 0)
+		return offset;
+
+	prop = fdt_getprop(fdt, offset, "machine-type", NULL);
+
+	if (! prop)
+		return 2;
+
+	dt_mach_type = fdt32_to_cpu(*prop);
+
+	return mach_type == dt_mach_type;
+}
+
+void put_dt_match_str(int match, unsigned int mach_type)
+{
+	switch (match) {
+	case 2:
+		putstr("'machine-type' property not found.");
+		putstr(" Device tree matched by default\n");
+		break;
+	case 1:
+		putstr("Device tree matched (machine type: ");
+		puthex(mach_type);
+		putstr(")\n");
+		break;
+	case 0:
+		putstr("Device tree not matched (machine type: ");
+		puthex(mach_type);
+		putstr(")\n");
+		break;
+	case -1:
+		/*
+		 * -1 means 'no device tree appended' so don't display any
+		 * message
+		 */
+		break;
+	default:
+		putstr("Unknown device tree match type.\n");
+	}
+}
+
 /*
  * gzip delarations
  */




More information about the linux-arm-kernel mailing list