diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/Kconfig | 20 | ||||
-rw-r--r-- | arch/arm/boot/compressed/head.S | 70 |
2 files changed, 87 insertions, 3 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5ebc5d922ea..c66e0808c2b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1781,6 +1781,26 @@ config ZBOOT_ROM_SH_MOBILE_SDHI endchoice +config ARM_APPENDED_DTB + bool "Use appended device tree blob to zImage (EXPERIMENTAL)" + depends on OF && !ZBOOT_ROM && EXPERIMENTAL + help + With this option, the boot code will look for a device tree binary + (DTB) appended to zImage + (e.g. cat zImage <filename>.dtb > zImage_w_dtb). + + This is meant as a backward compatibility convenience for those + systems with a bootloader that can't be upgraded to accommodate + the documented boot protocol using a device tree. + + Beware that there is very little in terms of protection against + this option being confused by leftover garbage in memory that might + look like a DTB header after a reboot if no actual DTB is appended + to zImage. Do not leave this option active in a production kernel + if you don't intend to always append a DTB. Proper passing of the + location into r2 of a bootloader provided DTB is always preferable + to this option. + config CMDLINE string "Default kernel command string" default "" diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index e95a5989602..3ce5738ddb9 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -216,6 +216,59 @@ restart: adr r0, LC0 mov r10, r6 #endif + mov r5, #0 @ init dtb size to 0 +#ifdef CONFIG_ARM_APPENDED_DTB +/* + * r0 = delta + * r2 = BSS start + * r3 = BSS end + * r4 = final kernel address + * r5 = appended dtb size (still unknown) + * r6 = _edata + * r7 = architecture ID + * r8 = atags/device tree pointer + * r9 = size of decompressed image + * r10 = end of this image, including bss/stack/malloc space if non XIP + * r11 = GOT start + * r12 = GOT end + * sp = stack pointer + * + * 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. + */ + + ldr lr, [r6, #0] +#ifndef __ARMEB__ + ldr r1, =0xedfe0dd0 @ sig is 0xd00dfeed big endian +#else + ldr r1, =0xd00dfeed +#endif + cmp lr, r1 + bne dtb_check_done @ not found + + mov r8, r6 @ use the appended device tree + + /* Get the dtb's size */ + ldr r5, [r6, #4] +#ifndef __ARMEB__ + /* convert r5 (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 +#endif + + /* preserve 64-bit alignment */ + add r5, r5, #7 + bic r5, r5, #7 + + /* relocate some pointers past the appended dtb */ + add r6, r6, r5 + add r10, r10, r5 + add sp, sp, r5 +dtb_check_done: +#endif + /* * Check to see if we will overwrite ourselves. * r4 = final kernel address @@ -285,14 +338,16 @@ wont_overwrite: * r2 = BSS start * r3 = BSS end * r4 = kernel execution address + * r5 = appended dtb size (0 if not present) * r7 = architecture ID * r8 = atags pointer * r11 = GOT start * r12 = GOT end * sp = stack pointer */ - teq r0, #0 + orrs r1, r0, r5 beq not_relocated + add r11, r11, r0 add r12, r12, r0 @@ -307,12 +362,21 @@ wont_overwrite: /* * Relocate all entries in the GOT table. + * Bump bss entries to _edata + dtb size */ 1: ldr r1, [r11, #0] @ relocate entries in the GOT - add r1, r1, r0 @ table. This fixes up the - str r1, [r11], #4 @ C references. + add r1, r1, r0 @ This fixes up C references + cmp r1, r2 @ if entry >= bss_start && + cmphs r3, r1 @ bss_end > entry + addhi r1, r1, r5 @ entry += dtb size + str r1, [r11], #4 @ next entry cmp r11, r12 blo 1b + + /* bump our bss pointers too */ + add r2, r2, r5 + add r3, r3, r5 + #else /* |