diff --git a/arch/arm/cpu/start-pbl.c b/arch/arm/cpu/start-pbl.c index f723edc61..5f1469bb3 100644 --- a/arch/arm/cpu/start-pbl.c +++ b/arch/arm/cpu/start-pbl.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "mmu-early.h" @@ -49,7 +50,7 @@ __noreturn void barebox_single_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata) { uint32_t offset; - uint32_t pg_start, pg_end, pg_len; + uint32_t pg_start, pg_end, pg_len, uncompressed_len; void __noreturn (*barebox)(unsigned long, unsigned long, void *); uint32_t endmem = membase + memsize; unsigned long barebox_base; @@ -63,9 +64,10 @@ __noreturn void barebox_single_pbl_start(unsigned long membase, pg_start = (uint32_t)&input_data - offset; pg_end = (uint32_t)&input_data_end - offset; pg_len = pg_end - pg_start; + uncompressed_len = get_unaligned((const u32 *)(pg_start + pg_len - 4)); if (IS_ENABLED(CONFIG_RELOCATABLE)) - barebox_base = arm_mem_barebox_image(membase, endmem, pg_len); + barebox_base = arm_mem_barebox_image(membase, endmem, uncompressed_len + MAX_BSS_SIZE); else barebox_base = TEXT_BASE; diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c index f25e5928c..0120117e0 100644 --- a/arch/arm/cpu/start.c +++ b/arch/arm/cpu/start.c @@ -143,8 +143,7 @@ __noreturn void barebox_non_pbl_start(unsigned long membase, { unsigned long endmem = membase + memsize; unsigned long malloc_start, malloc_end; - unsigned long barebox_size = barebox_image_size + - ((unsigned long)&__bss_stop - (unsigned long)&__bss_start); + unsigned long barebox_size = barebox_image_size + MAX_BSS_SIZE; if (IS_ENABLED(CONFIG_RELOCATABLE)) { unsigned long barebox_base = arm_mem_barebox_image(membase, diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c index b8e2e9ffd..eeb5a6543 100644 --- a/arch/arm/cpu/uncompress.c +++ b/arch/arm/cpu/uncompress.c @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -44,7 +45,7 @@ static int __attribute__((__used__)) void __noreturn barebox_multi_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata) { - uint32_t pg_len; + uint32_t pg_len, uncompressed_len; void __noreturn (*barebox)(unsigned long, unsigned long, void *); uint32_t endmem = membase + memsize; unsigned long barebox_base; @@ -72,10 +73,11 @@ void __noreturn barebox_multi_pbl_start(unsigned long membase, */ pg_start = image_end + 1; pg_len = *(image_end); + uncompressed_len = get_unaligned((const u32 *)(pg_start + pg_len - 4)); if (IS_ENABLED(CONFIG_RELOCATABLE)) barebox_base = arm_mem_barebox_image(membase, endmem, - pg_len); + uncompressed_len + MAX_BSS_SIZE); else barebox_base = TEXT_BASE; @@ -92,8 +94,8 @@ void __noreturn barebox_multi_pbl_start(unsigned long membase, free_mem_ptr = arm_mem_early_malloc(membase, endmem); free_mem_end_ptr = arm_mem_early_malloc_end(membase, endmem); - pr_debug("uncompressing barebox binary at 0x%p (size 0x%08x) to 0x%08lx\n", - pg_start, pg_len, barebox_base); + pr_debug("uncompressing barebox binary at 0x%p (size 0x%08x) to 0x%08lx (uncompressed size: 0x%08x)\n", + pg_start, pg_len, barebox_base, uncompressed_len); pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len); diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h index 0acdfa3db..061296a47 100644 --- a/arch/arm/include/asm/barebox-arm.h +++ b/arch/arm/include/asm/barebox-arm.h @@ -164,6 +164,13 @@ static inline unsigned long arm_mem_barebox_image(unsigned long membase, static void __naked noinline __##name \ (uint32_t arg0, uint32_t arg1, uint32_t arg2) - +/* + * When using compressed images in conjunction with relocatable images + * the PBL code must pick a suitable place where to uncompress the barebox + * image. For doing this the PBL code must know the size of the final + * image including the BSS segment. The BSS size is unknown to the PBL + * code, so define a maximum BSS size here. + */ +#define MAX_BSS_SIZE SZ_1M #endif /* _BAREBOX_ARM_H_ */