diff options
-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 5ebc5d922ea1..c66e0808c2b1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -1781,6 +1781,26 @@ config ZBOOT_ROM_SH_MOBILE_SDHI | |||
1781 | 1781 | ||
1782 | endchoice | 1782 | endchoice |
1783 | 1783 | ||
1784 | config ARM_APPENDED_DTB | ||
1785 | bool "Use appended device tree blob to zImage (EXPERIMENTAL)" | ||
1786 | depends on OF && !ZBOOT_ROM && EXPERIMENTAL | ||
1787 | help | ||
1788 | With this option, the boot code will look for a device tree binary | ||
1789 | (DTB) appended to zImage | ||
1790 | (e.g. cat zImage <filename>.dtb > zImage_w_dtb). | ||
1791 | |||
1792 | This is meant as a backward compatibility convenience for those | ||
1793 | systems with a bootloader that can't be upgraded to accommodate | ||
1794 | the documented boot protocol using a device tree. | ||
1795 | |||
1796 | Beware that there is very little in terms of protection against | ||
1797 | this option being confused by leftover garbage in memory that might | ||
1798 | look like a DTB header after a reboot if no actual DTB is appended | ||
1799 | to zImage. Do not leave this option active in a production kernel | ||
1800 | if you don't intend to always append a DTB. Proper passing of the | ||
1801 | location into r2 of a bootloader provided DTB is always preferable | ||
1802 | to this option. | ||
1803 | |||
1784 | config CMDLINE | 1804 | config CMDLINE |
1785 | string "Default kernel command string" | 1805 | string "Default kernel command string" |
1786 | default "" | 1806 | default "" |
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index e95a5989602a..3ce5738ddb98 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -216,6 +216,59 @@ restart: adr r0, LC0 | |||
216 | mov r10, r6 | 216 | mov r10, r6 |
217 | #endif | 217 | #endif |
218 | 218 | ||
219 | mov r5, #0 @ init dtb size to 0 | ||
220 | #ifdef CONFIG_ARM_APPENDED_DTB | ||
221 | /* | ||
222 | * r0 = delta | ||
223 | * r2 = BSS start | ||
224 | * r3 = BSS end | ||
225 | * r4 = final kernel address | ||
226 | * r5 = appended dtb size (still unknown) | ||
227 | * r6 = _edata | ||
228 | * r7 = architecture ID | ||
229 | * r8 = atags/device tree pointer | ||
230 | * r9 = size of decompressed image | ||
231 | * r10 = end of this image, including bss/stack/malloc space if non XIP | ||
232 | * r11 = GOT start | ||
233 | * r12 = GOT end | ||
234 | * sp = stack pointer | ||
235 | * | ||
236 | * if there are device trees (dtb) appended to zImage, advance r10 so that the | ||
237 | * dtb data will get relocated along with the kernel if necessary. | ||
238 | */ | ||
239 | |||
240 | ldr lr, [r6, #0] | ||
241 | #ifndef __ARMEB__ | ||
242 | ldr r1, =0xedfe0dd0 @ sig is 0xd00dfeed big endian | ||
243 | #else | ||
244 | ldr r1, =0xd00dfeed | ||
245 | #endif | ||
246 | cmp lr, r1 | ||
247 | bne dtb_check_done @ not found | ||
248 | |||
249 | mov r8, r6 @ use the appended device tree | ||
250 | |||
251 | /* Get the dtb's size */ | ||
252 | ldr r5, [r6, #4] | ||
253 | #ifndef __ARMEB__ | ||
254 | /* convert r5 (dtb size) to little endian */ | ||
255 | eor r1, r5, r5, ror #16 | ||
256 | bic r1, r1, #0x00ff0000 | ||
257 | mov r5, r5, ror #8 | ||
258 | eor r5, r5, r1, lsr #8 | ||
259 | #endif | ||
260 | |||
261 | /* preserve 64-bit alignment */ | ||
262 | add r5, r5, #7 | ||
263 | bic r5, r5, #7 | ||
264 | |||
265 | /* relocate some pointers past the appended dtb */ | ||
266 | add r6, r6, r5 | ||
267 | add r10, r10, r5 | ||
268 | add sp, sp, r5 | ||
269 | dtb_check_done: | ||
270 | #endif | ||
271 | |||
219 | /* | 272 | /* |
220 | * Check to see if we will overwrite ourselves. | 273 | * Check to see if we will overwrite ourselves. |
221 | * r4 = final kernel address | 274 | * r4 = final kernel address |
@@ -285,14 +338,16 @@ wont_overwrite: | |||
285 | * r2 = BSS start | 338 | * r2 = BSS start |
286 | * r3 = BSS end | 339 | * r3 = BSS end |
287 | * r4 = kernel execution address | 340 | * r4 = kernel execution address |
341 | * r5 = appended dtb size (0 if not present) | ||
288 | * r7 = architecture ID | 342 | * r7 = architecture ID |
289 | * r8 = atags pointer | 343 | * r8 = atags pointer |
290 | * r11 = GOT start | 344 | * r11 = GOT start |
291 | * r12 = GOT end | 345 | * r12 = GOT end |
292 | * sp = stack pointer | 346 | * sp = stack pointer |
293 | */ | 347 | */ |
294 | teq r0, #0 | 348 | orrs r1, r0, r5 |
295 | beq not_relocated | 349 | beq not_relocated |
350 | |||
296 | add r11, r11, r0 | 351 | add r11, r11, r0 |
297 | add r12, r12, r0 | 352 | add r12, r12, r0 |
298 | 353 | ||
@@ -307,12 +362,21 @@ wont_overwrite: | |||
307 | 362 | ||
308 | /* | 363 | /* |
309 | * Relocate all entries in the GOT table. | 364 | * Relocate all entries in the GOT table. |
365 | * Bump bss entries to _edata + dtb size | ||
310 | */ | 366 | */ |
311 | 1: ldr r1, [r11, #0] @ relocate entries in the GOT | 367 | 1: ldr r1, [r11, #0] @ relocate entries in the GOT |
312 | add r1, r1, r0 @ table. This fixes up the | 368 | add r1, r1, r0 @ This fixes up C references |
313 | str r1, [r11], #4 @ C references. | 369 | cmp r1, r2 @ if entry >= bss_start && |
370 | cmphs r3, r1 @ bss_end > entry | ||
371 | addhi r1, r1, r5 @ entry += dtb size | ||
372 | str r1, [r11], #4 @ next entry | ||
314 | cmp r11, r12 | 373 | cmp r11, r12 |
315 | blo 1b | 374 | blo 1b |
375 | |||
376 | /* bump our bss pointers too */ | ||
377 | add r2, r2, r5 | ||
378 | add r3, r3, r5 | ||
379 | |||
316 | #else | 380 | #else |
317 | 381 | ||
318 | /* | 382 | /* |