[PATCH 9/9] Add compressed image support
Jean-Christophe PLAGNIOL-VILLARD
plagnioj at jcrosoft.com
Thu Jul 19 10:10:42 EDT 2012
On 10:13 Thu 19 Jul , Sascha Hauer wrote:
> This allows for creating a lzo compressed binary. This is done by
> linking barebox twice using two linker scripts. One is the regular
> uncompressed binary but without the lowlevel init stuff. The
> other contains the lowlevel init stuff, the decompressor and the
> compressed binary.
>
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
> Makefile | 31 +++++++++++++-
> arch/arm/Kconfig | 1 +
> arch/arm/Makefile | 1 +
> arch/arm/cpu/start.c | 73 +++++++++++++++++++++++++++++++--
> arch/arm/lib/Makefile | 1 +
> arch/arm/lib/barebox-compressed.lds.S | 71 ++++++++++++++++++++++++++++++++
> arch/arm/lib/barebox.lds.S | 3 +-
> common/Kconfig | 12 ++++++
> include/asm-generic/memory_layout.h | 2 +
> lib/vsprintf.c | 25 ++++++++++-
> piggy.lzo.S | 6 +++
> 11 files changed, 220 insertions(+), 6 deletions(-)
> create mode 100644 arch/arm/lib/barebox-compressed.lds.S
> create mode 100644 piggy.lzo.S
>
> diff --git a/Makefile b/Makefile
> index ebcf9bf..3ade6cc 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -512,6 +512,7 @@ common-y := $(patsubst %/, %/built-in.o, $(common-y))
> barebox-common := $(common-y)
> barebox-all := $(barebox-common)
> barebox-lds := $(lds-y)
> +barebox-compressed-lds := $(lds-compressed-y)
>
> # Rule to link barebox
> # May be overridden by arch/$(ARCH)/Makefile
> @@ -667,6 +668,7 @@ quiet_cmd_objcopy = OBJCOPY $@
> cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
>
> OBJCOPYFLAGS_barebox.bin = -O binary
> +OBJCOPYFLAGS_barebox-uncompressed.bin = -O binary
>
> barebox.bin: barebox FORCE
> $(call if_changed,objcopy)
> @@ -700,13 +702,39 @@ quiet_cmd_disasm = DISASM $@
>
> barebox.S: barebox FORCE
> $(call if_changed,disasm)
> +barebox-uncompressed.S: barebox-uncompressed FORCE
> + $(call if_changed,disasm)
> endif
>
> # barebox image
> +barebox-uncompressed: $(barebox-lds) $(barebox-head) $(barebox-common) $(kallsyms.o)
> + $(call barebox-modpost)
> + $(call if_changed_rule,barebox__)
> + $(Q)rm -f .old_version
> +
> +barebox-uncompressed.bin: barebox-uncompressed
> + $(call if_changed,objcopy)
> +
> +barebox-uncompressed.bin.lzo: barebox-uncompressed.bin
> + @echo " LZO " $@
> + $(Q)lzop -f -9 -o $@ barebox-uncompressed.bin
> +
> +piggy.lzo.o: barebox-uncompressed.bin.lzo piggy.lzo.S
> + @echo " CC " $@
> + $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) -c piggy.lzo.S -o $@
> +
> +ifdef CONFIG_IMAGE_COMPRESSION_LZO
> +barebox: piggy.lzo.o
> + @echo " LD " $@
> + $(Q)$(LD) $(LDFLAGS) $(LDFLAGS_barebox) -o $@ \
> + -T $(barebox-compressed-lds) $(barebox-compressed) \
> + --start-group $(barebox-common) piggy.lzo.o --end-group
> +else
> barebox: $(barebox-lds) $(barebox-head) $(barebox-common) $(kallsyms.o) FORCE
> $(call barebox-modpost)
> $(call if_changed_rule,barebox__)
> $(Q)rm -f .old_version
> +endif
>
> barebox.srec: barebox
> $(OBJCOPY) -O srec $< $@
> @@ -1004,7 +1032,8 @@ CLEAN_FILES += barebox System.map include/generated/barebox_default_env.h \
> .tmp_version .tmp_barebox* barebox.bin barebox.map barebox.S \
> .tmp_kallsyms* barebox_default_env* barebox.ldr \
> scripts/bareboxenv-target \
> - Doxyfile.version barebox.srec barebox.s5p
> + Doxyfile.version barebox.srec barebox.s5p \
> + barebox-uncompressed barebox-uncompressed.bin barebox-uncompressed.bin.lzo
>
> # Directories & files removed with 'make mrproper'
> MRPROPER_DIRS += include/config include2 usr/include
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index d988455..2396bae 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -4,6 +4,7 @@ config ARM
> select HAS_MODULES
> select HAVE_CONFIGURABLE_MEMORY_LAYOUT
> select HAVE_CONFIGURABLE_TEXT_BASE
> + select HAVE_IMAGE_COMPRESSION
> default y
>
> config ARM_AMBA
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index cbbc0a0..a93c4d5 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -208,5 +208,6 @@ common-y += $(BOARD) $(MACH)
> common-y += arch/arm/lib/ arch/arm/cpu/
>
> lds-y := arch/arm/lib/barebox.lds
> +lds-compressed-y := arch/arm/lib/barebox-compressed.lds
>
> CLEAN_FILES += include/generated/mach-types.h arch/arm/lib/barebox.lds
> diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
> index cabe4d2..f4aeefe 100644
> --- a/arch/arm/cpu/start.c
> +++ b/arch/arm/cpu/start.c
> @@ -28,16 +28,36 @@
> #include <asm-generic/memory_layout.h>
> #include <asm/sections.h>
>
> +#ifdef CONFIG_IMAGE_COMPRESSION_LZO
> +void __naked __section(.text_head_entry) compressed_start(void)
> +{
> + barebox_arm_head();
> +}
> +
> +void __naked __section(.text_entry) start(void)
can we have a have for all of the __section stuff
> +{
> + u32 r;
> +
> + /* Setup the stack */
> + r = STACK_BASE + STACK_SIZE - 16;
> + __asm__ __volatile__("mov sp, %0" : : "r"(r));
> + /* clear bss */
> + memset(__bss_start, 0, __bss_stop - __bss_start);
> +
> + start_barebox();
> +}
> +#else
> void __naked __section(.text_entry) start(void)
> {
> barebox_arm_head();
> }
> +#endif
>
> void __naked __section(.text_exceptions) exception_vectors(void)
> {
> __asm__ __volatile__ (
> ".arm\n"
> - "b reset\n" /* reset */
> + "1: b 1b\n" /* reset */
> #ifdef CONFIG_ARM_EXCEPTIONS
> "ldr pc, =undefined_instruction\n" /* undefined instruction */
> "ldr pc, =software_interrupt\n" /* software interrupt (SWI) */
> @@ -98,6 +118,34 @@ void __naked __bare_init reset(void)
> board_init_lowlevel_return();
> }
>
> +extern void *input_data;
> +extern void *input_data_end;
> +
> +#define STATIC static
> +#include "../../../lib/decompress_unlzo.c"
> +
> +void barebox_uncompress(void *compressed_start, unsigned int len)
> +{
> + void (*barebox)(void);
> +
> +#ifdef CONFIG_THUMB2_BAREBOX
> + barebox = (void *)(TEXT_BASE + 1);
> +#else
> + barebox = (void *)TEXT_BASE;
> +#endif
I hate the ifdef please use if (IS_ENABLED(x))
> +
> + decompress_unlzo((void *)compressed_start,
> + len,
> + NULL, NULL,
> + (void *)TEXT_BASE, NULL, NULL);
> +
> + /* flush I-cache before jumping to the uncompressed binary */
> + __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
macro or inline?
> +
> + barebox();
> +}
> +
> +
> /*
> * Board code can jump here by either returning from board_init_lowlevel
> * or by calling this function directly.
> @@ -105,7 +153,10 @@ void __naked __bare_init reset(void)
> void __naked __section(.text_ll_return) board_init_lowlevel_return(void)
> {
> uint32_t r, addr, offset;
> -
> +#ifdef CONFIG_IMAGE_COMPRESSION_LZO
> + uint32_t compressed_start, compressed_end, len;
> + void (*uncompress)(void *compressed_start, unsigned int len);
> +#endif
> /*
> * Get runtime address of this function. Do not
> * put any code above this.
> @@ -130,8 +181,24 @@ void __naked __section(.text_ll_return) board_init_lowlevel_return(void)
> /* flush I-cache before jumping to the copied binary */
> __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
>
> +#ifdef CONFIG_IMAGE_COMPRESSION_LZO
> + compressed_start = (uint32_t)&input_data - offset;
> + compressed_end = (uint32_t)&input_data_end - offset;
> + len = compressed_end - compressed_start;
> +
> + uncompress = barebox_uncompress;
> +
> + /* call start_barebox with its absolute address */
> + __asm__ __volatile__(
> + "mov r0, %1\n"
> + "mov r1, %2\n"
> + "mov pc, %0\n"
> + :
> + : "r"(uncompress), "r"(compressed_start), "r"(len)
> + : "r0", "r1");
> +#else
> /* call start_barebox with its absolute address */
> r = (unsigned int)&start_barebox;
> __asm__ __volatile__("mov pc, %0" : : "r"(r));
> +#endif
ifdef rrrr :(
> }
> -
> diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
> index 1eaf474..044d3e6 100644
> --- a/arch/arm/lib/Makefile
> +++ b/arch/arm/lib/Makefile
> @@ -21,3 +21,4 @@ obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memset.o
> obj-$(CONFIG_ARM_UNWIND) += unwind.o
> obj-$(CONFIG_MODULES) += module.o
> extra-y += barebox.lds
> +extra-$(CONFIG_IMAGE_COMPRESSION_LZO) += barebox-compressed.lds
> diff --git a/arch/arm/lib/barebox-compressed.lds.S b/arch/arm/lib/barebox-compressed.lds.S
> new file mode 100644
> index 0000000..f267da9
> --- /dev/null
> +++ b/arch/arm/lib/barebox-compressed.lds.S
> @@ -0,0 +1,71 @@
> +/*
> + * (C) Copyright 2000-2004
> + * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
you can put you onw copyright
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + *
> + */
> +
> +#include <asm-generic/barebox.lds.h>
> +#include <asm-generic/memory_layout.h>
> +
> +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
> +OUTPUT_ARCH(arm)
> +ENTRY(compressed_start)
> +SECTIONS
> +{
> + . = HEAD_TEXT_BASE;
> +
> + PRE_IMAGE
> +
> + . = ALIGN(4);
> + .text :
> + {
> + _stext = .;
> + _text = .;
> + *(.text_head_entry*)
> + __ll_return = .;
> + *(.text_ll_return*)
> + __bare_init_start = .;
> + *(.text_bare_init*)
> + __bare_init_end = .;
> + *(.text*)
> + }
macro?
> + BAREBOX_BARE_INIT_SIZE
> +
> + . = ALIGN(4);
> + .rodata : { *(.rodata*) }
> +
> + _etext = .; /* End of text and rodata section */
> +
> + . = ALIGN(4);
> + .piggydata : {
> + *(.piggydata)
> + }
> +
> + . = ALIGN(4);
> + .data : { *(.data*) }
ditto
> +
> + . = ALIGN(4);
> + __bss_start = .;
> + .bss : { *(.bss*) }
> + __bss_stop = .;
ditto
> + _end = .;
> + _barebox_image_size = __bss_start - HEAD_TEXT_BASE;
ditto
> +}
> diff --git a/arch/arm/lib/barebox.lds.S b/arch/arm/lib/barebox.lds.S
> index e0bae70..b415830 100644
> --- a/arch/arm/lib/barebox.lds.S
> +++ b/arch/arm/lib/barebox.lds.S
> @@ -31,8 +31,9 @@ SECTIONS
> {
> . = TEXT_BASE;
>
> +#ifndef CONFIG_IMAGE_COMPRESSION_LZO
> PRE_IMAGE
> -
> +#endif
> . = ALIGN(4);
> .text :
> {
> diff --git a/common/Kconfig b/common/Kconfig
> index b776031..0e81b57 100644
> --- a/common/Kconfig
> +++ b/common/Kconfig
> @@ -93,6 +93,13 @@ config ENVIRONMENT_VARIABLES
>
> menu "memory layout "
>
> +config HAVE_IMAGE_COMPRESSION
> + bool
> +
> +config IMAGE_COMPRESSION_LZO
> + depends on HAVE_IMAGE_COMPRESSION
> + bool "lzo compressed image"
> +
> config MMU
> bool "Enable MMU"
> help
> @@ -173,6 +180,11 @@ config MALLOC_SIZE
> hex
> default 0x400000
> prompt "malloc area size"
> +
> +config HEAD_TEXT_BASE
> + depends on MEMORY_LAYOUT_FIXED && IMAGE_COMPRESSION_LZO
> + hex
> + prompt "HEAD_TEXT_BASE"
> endmenu
>
> config BROKEN
> diff --git a/include/asm-generic/memory_layout.h b/include/asm-generic/memory_layout.h
> index 941cd42..a5efaf0 100644
> --- a/include/asm-generic/memory_layout.h
> +++ b/include/asm-generic/memory_layout.h
> @@ -5,11 +5,13 @@
>
> #define MALLOC_BASE (TEXT_BASE - CONFIG_MALLOC_SIZE)
> #define STACK_BASE (TEXT_BASE - CONFIG_MALLOC_SIZE - CONFIG_STACK_SIZE)
> +#define HEAD_TEXT_BASE (TEXT_BASE - 0x100000)
>
> #else
>
> #define STACK_BASE CONFIG_STACK_BASE
> #define MALLOC_BASE CONFIG_MALLOC_BASE
> +#define HEAD_TEXT_BASE CONFIG_HEAD_TEXT_BASE
>
> #endif
>
> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> index 17c1973..3f23bf1 100644
> --- a/lib/vsprintf.c
> +++ b/lib/vsprintf.c
> @@ -18,6 +18,7 @@
> #include <kallsyms.h>
>
> #include <common.h>
> +#include <init.h>
> #include <led.h>
>
> unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
> @@ -618,7 +619,7 @@ char *asprintf(const char *fmt, ...)
> }
> EXPORT_SYMBOL(asprintf);
>
> -void __noreturn panic(const char *fmt, ...)
> +static void __noreturn __panic(const char *fmt, ...)
> {
> va_list args;
> va_start(args, fmt);
> @@ -637,4 +638,26 @@ void __noreturn panic(const char *fmt, ...)
> reset_cpu(0);
> #endif
> }
> +
> +static void (*panic_fn)(const char *fmt, ...);
how about have a default empty panic
> +
> +static int panic_init(void)
> +{
> + panic_fn = __panic;
> +
> + return 0;
> +}
> +core_initcall(panic_init);
> +
> +void __noreturn panic(const char *fmt, ...)
> +{
> + if (panic_fn) {
so we can drop the test
> + va_list args;
> + va_start(args, fmt);
> + panic_fn(fmt, args);
> + va_end(args);
> + }
> +
> + while(1);
> +}
Best Regrds,
J.
More information about the barebox
mailing list