summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2013-07-01 10:14:40 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2013-07-01 10:14:40 +0200
commit939c2173a3787daa36be6f5f67c72561f7665f65 (patch)
tree0de80442bce4c39234866a7adf6c3f24bd8e2560
parentae0589c5efd09e0b2f00edf4970442ad3b096179 (diff)
parent08c0e206b3614eeecc1c3cee63665077360212e5 (diff)
downloadbarebox-939c2173a3787daa36be6f5f67c72561f7665f65.tar.gz
barebox-939c2173a3787daa36be6f5f67c72561f7665f65.tar.xz
Merge branch 'for-next/multi-image'
-rw-r--r--Makefile10
-rw-r--r--arch/arm/Makefile2
-rw-r--r--arch/arm/boards/pcm038/lowlevel.c4
-rw-r--r--arch/arm/cpu/Makefile6
-rw-r--r--arch/arm/cpu/dtb.c22
-rw-r--r--arch/arm/cpu/start-images.c49
-rw-r--r--arch/arm/cpu/start.c20
-rw-r--r--arch/arm/cpu/uncompress.c108
-rw-r--r--arch/arm/dts/Makefile1
-rw-r--r--arch/arm/include/asm/barebox-arm-head.h14
-rw-r--r--arch/arm/include/asm/barebox-arm.h6
-rw-r--r--arch/arm/lib/pbl.lds.S (renamed from arch/arm/pbl/zbarebox.lds.S)9
-rw-r--r--arch/arm/lib/runtime-offset.S3
-rw-r--r--arch/arm/mach-imx/Kconfig2
-rw-r--r--arch/arm/pbl/Makefile5
-rw-r--r--drivers/of/Kconfig1
-rw-r--r--images/Makefile124
-rw-r--r--images/Makefile.imx15
-rw-r--r--include/asm-generic/sections.h1
-rw-r--r--pbl/Kconfig16
-rw-r--r--scripts/Makefile.lib2
21 files changed, 407 insertions, 13 deletions
diff --git a/Makefile b/Makefile
index 8c1becbc0c..9afe3058f3 100644
--- a/Makefile
+++ b/Makefile
@@ -481,7 +481,16 @@ export KBUILD_BINARY ?= barebox.bin
barebox-flash-image: $(KBUILD_IMAGE) FORCE
$(call if_changed,ln)
+images: barebox.bin FORCE
+ $(Q)$(MAKE) $(build)=images $@
+images/%.s: barebox.bin FORCE
+ $(Q)$(MAKE) $(build)=images $@
+
+ifdef CONFIG_PBL_MULTI_IMAGES
+all: $(KBUILD_DTBS) barebox.bin images
+else
all: barebox-flash-image $(KBUILD_DTBS)
+endif
common-$(CONFIG_PBL_IMAGE) += pbl/
@@ -987,6 +996,7 @@ clean-dirs := $(addprefix _clean_,$(srctree) $(barebox-alldirs))
PHONY += $(clean-dirs) clean archclean
$(clean-dirs):
+ $(Q)$(MAKE) $(clean)=images
$(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
clean: archclean $(clean-dirs)
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 32bdd65a21..658b1a5cc0 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -328,7 +328,7 @@ endif
common-y += $(BOARD) $(MACH)
common-y += arch/arm/lib/ arch/arm/cpu/
-common-$(CONFIG_BUILTIN_DTB) += arch/arm/dts/
+common-$(CONFIG_OFTREE) += arch/arm/dts/
lds-y := arch/arm/lib/barebox.lds
diff --git a/arch/arm/boards/pcm038/lowlevel.c b/arch/arm/boards/pcm038/lowlevel.c
index 0ea293981b..a3b2d1315a 100644
--- a/arch/arm/boards/pcm038/lowlevel.c
+++ b/arch/arm/boards/pcm038/lowlevel.c
@@ -33,11 +33,13 @@
#define ESDCTL0_VAL (ESDCTL0_SDE | ESDCTL0_ROW13 | ESDCTL0_COL10)
-void __bare_init __naked barebox_arm_reset_vector(void)
+ENTRY_FUNCTION(start_imx27_pcm038)(void)
{
uint32_t r;
int i;
+ __barebox_arm_head();
+
arm_cpu_lowlevel_init();
/* ahb lite ip interface */
diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
index c442b35797..fba8ff2784 100644
--- a/arch/arm/cpu/Makefile
+++ b/arch/arm/cpu/Makefile
@@ -8,7 +8,7 @@ obj-y += start.o setupc.o
#
obj-$(CONFIG_CMD_ARM_CPUINFO) += cpuinfo.o
obj-$(CONFIG_CMD_ARM_MMUINFO) += mmuinfo.o
-obj-$(CONFIG_BUILTIN_DTB) += dtb.o
+obj-$(CONFIG_OFDEVICE) += dtb.o
obj-$(CONFIG_MMU) += mmu.o cache.o mmu-early.o
pbl-$(CONFIG_MMU) += cache.o mmu-early.o
obj-$(CONFIG_CPU_32v4T) += cache-armv4.o
@@ -21,7 +21,9 @@ obj-$(CONFIG_CPU_32v7) += cache-armv7.o
pbl-$(CONFIG_CPU_32v7) += cache-armv7.o
obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
-pbl-y += start-pbl.o setupc.o
+pbl-y += setupc.o
+pbl-$(CONFIG_PBL_SINGLE_IMAGE) += start-pbl.o
+pbl-$(CONFIG_PBL_MULTI_IMAGES) += start-images.o uncompress.o
obj-y += common.o
pbl-y += common.o
diff --git a/arch/arm/cpu/dtb.c b/arch/arm/cpu/dtb.c
index 10b73bd519..a5881dd721 100644
--- a/arch/arm/cpu/dtb.c
+++ b/arch/arm/cpu/dtb.c
@@ -17,20 +17,38 @@
#include <common.h>
#include <init.h>
#include <of.h>
+#include <asm/barebox-arm.h>
extern char __dtb_start[];
static int of_arm_init(void)
{
struct device_node *root;
+ void *fdt;
+ /* See if we already have a dtb */
root = of_get_root_node();
if (root)
return 0;
- root = of_unflatten_dtb(NULL, __dtb_start);
- if (root) {
+ /* See if we are provided a dtb in boarddata */
+ fdt = barebox_arm_boot_dtb();
+ if (fdt)
+ pr_debug("using boarddata provided DTB\n");
+
+ /* Next see if we have a builtin dtb */
+ if (!fdt && IS_ENABLED(CONFIG_BUILTIN_DTB)) {
+ fdt = __dtb_start;
pr_debug("using internal DTB\n");
+ }
+
+ if (!fdt) {
+ pr_debug("No DTB found\n");
+ return 0;
+ }
+
+ root = of_unflatten_dtb(NULL, fdt);
+ if (root) {
of_set_root_node(root);
if (IS_ENABLED(CONFIG_OFDEVICE))
of_probe();
diff --git a/arch/arm/cpu/start-images.c b/arch/arm/cpu/start-images.c
new file mode 100644
index 0000000000..d48d245294
--- /dev/null
+++ b/arch/arm/cpu/start-images.c
@@ -0,0 +1,49 @@
+/*
+ * start-pbl.c
+ *
+ * Copyright (c) 2010-2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ * Copyright (c) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * 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 version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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 <common.h>
+#include <init.h>
+#include <sizes.h>
+#include <pbl.h>
+#include <asm/barebox-arm.h>
+#include <asm/barebox-arm-head.h>
+#include <asm-generic/memory_layout.h>
+#include <asm/sections.h>
+#include <asm/pgtable.h>
+#include <debug_ll.h>
+
+void __naked __noreturn barebox_arm_entry(uint32_t membase, uint32_t memsize,
+ uint32_t boarddata)
+{
+ unsigned long barebox_base;
+ void __noreturn (*barebox)(uint32_t, uint32_t, uint32_t);
+
+ barebox_base = ld_var(__image_end) - get_runtime_offset() + 4;
+
+ if (IS_ENABLED(CONFIG_THUMB2_BAREBOX))
+ barebox = (void *)(barebox_base + 1);
+ else
+ barebox = (void *)barebox_base;
+
+ barebox(membase, memsize, boarddata);
+}
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index 5a3c629c73..1f397ec789 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -24,6 +24,7 @@
#include <asm/barebox-arm-head.h>
#include <asm-generic/memory_layout.h>
#include <asm/sections.h>
+#include <asm/unaligned.h>
#include <asm/cache.h>
#include <memory.h>
@@ -40,6 +41,13 @@ unsigned long barebox_arm_boarddata(void)
return barebox_boarddata;
}
+static void *barebox_boot_dtb;
+
+void *barebox_arm_boot_dtb(void)
+{
+ return barebox_boot_dtb;
+}
+
static noinline __noreturn void __start(uint32_t membase, uint32_t memsize,
uint32_t boarddata)
{
@@ -66,6 +74,18 @@ static noinline __noreturn void __start(uint32_t membase, uint32_t memsize,
mmu_early_enable(membase, memsize, endmem);
}
+ /*
+ * If boarddata is a pointer inside valid memory and contains a
+ * FDT magic then use it as later to probe devices
+ */
+ if (boarddata > membase && boarddata < membase + memsize &&
+ get_unaligned_be32((void *)boarddata) == FDT_MAGIC) {
+ uint32_t totalsize = get_unaligned_be32((void *)boarddata + 4);
+ endmem -= ALIGN(totalsize, 64);
+ barebox_boot_dtb = (void *)endmem;
+ memcpy(barebox_boot_dtb, (void *)boarddata, totalsize);
+ }
+
if ((unsigned long)_text > membase + memsize ||
(unsigned long)_text < membase)
/*
diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
new file mode 100644
index 0000000000..b401f8efe2
--- /dev/null
+++ b/arch/arm/cpu/uncompress.c
@@ -0,0 +1,108 @@
+/*
+ * uncompress.c - uncompressor code for self extracing pbl image
+ *
+ * Copyright (c) 2010-2013 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ * Copyright (c) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * 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 version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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 <common.h>
+#include <init.h>
+#include <sizes.h>
+#include <pbl.h>
+#include <asm/barebox-arm.h>
+#include <asm/barebox-arm-head.h>
+#include <asm-generic/memory_layout.h>
+#include <asm/sections.h>
+#include <asm/pgtable.h>
+#include <asm/cache.h>
+
+#include <debug_ll.h>
+
+#include "mmu-early.h"
+
+unsigned long free_mem_ptr;
+unsigned long free_mem_end_ptr;
+
+static int __attribute__((__used__))
+ __attribute__((__section__(".image_end")))
+ __image_end_dummy = 0xdeadbeef;
+
+static void noinline uncompress(uint32_t membase,
+ uint32_t memsize, uint32_t boarddata)
+{
+ uint32_t offset;
+ uint32_t pg_len;
+ void __noreturn (*barebox)(uint32_t, uint32_t, uint32_t);
+ uint32_t endmem = membase + memsize;
+ unsigned long barebox_base;
+ uint32_t *ptr;
+ void *pg_start;
+
+ endmem -= STACK_SIZE; /* stack */
+
+ if (IS_ENABLED(CONFIG_PBL_RELOCATABLE))
+ relocate_to_current_adr();
+
+ /* Get offset between linked address and runtime address */
+ offset = get_runtime_offset();
+
+ if (IS_ENABLED(CONFIG_RELOCATABLE))
+ barebox_base = arm_barebox_image_place(membase + memsize);
+ else
+ barebox_base = TEXT_BASE;
+
+ setup_c();
+
+ if (IS_ENABLED(CONFIG_MMU_EARLY)) {
+ endmem &= ~0x3fff;
+ endmem -= SZ_16K; /* ttb */
+ mmu_early_enable(membase, memsize, endmem);
+ }
+
+ endmem -= SZ_128K; /* early malloc */
+ free_mem_ptr = endmem;
+ free_mem_end_ptr = free_mem_ptr + SZ_128K;
+
+ ptr = (void *)__image_end;
+ pg_start = ptr + 1;
+ pg_len = *(ptr);
+
+ pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len);
+
+ arm_early_mmu_cache_flush();
+ flush_icache();
+
+ if (IS_ENABLED(CONFIG_THUMB2_BAREBOX))
+ barebox = (void *)(barebox_base + 1);
+ else
+ barebox = (void *)barebox_base;
+
+ barebox(membase, memsize, boarddata);
+}
+
+/*
+ * Generic second stage pbl uncompressor entry
+ */
+ENTRY_FUNCTION(start_uncompress)(uint32_t membase, uint32_t memsize,
+ uint32_t boarddata)
+{
+ arm_setup_stack(membase + memsize - 16);
+
+ uncompress(membase, memsize, boarddata);
+}
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index b271618c56..678f910c50 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -9,6 +9,7 @@ BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_NAME))
obj-$(CONFIG_BUILTIN_DTB) += $(BUILTIN_DTB).dtb.o
.SECONDARY: $(obj)/$(BUILTIN_DTB).dtb.S
+.SECONDARY: $(patsubst %,$(obj)/%.S,$(dtb-y))
targets += dtbs
targets += $(dtb-y)
diff --git a/arch/arm/include/asm/barebox-arm-head.h b/arch/arm/include/asm/barebox-arm-head.h
index 9a8cc87716..af7164a2eb 100644
--- a/arch/arm/include/asm/barebox-arm-head.h
+++ b/arch/arm/include/asm/barebox-arm-head.h
@@ -43,7 +43,7 @@ static inline void arm_cpu_lowlevel_init(void)
#ifdef CONFIG_HAVE_MACH_ARM_HEAD
#include <mach/barebox-arm-head.h>
#else
-static inline void barebox_arm_head(void)
+static inline void __barebox_arm_head(void)
{
__asm__ __volatile__ (
#ifdef CONFIG_THUMB2_BAREBOX
@@ -52,12 +52,12 @@ static inline void barebox_arm_head(void)
"bx r9\n"
".thumb\n"
"1:\n"
- "bl barebox_arm_reset_vector\n"
+ "bl 2f\n"
".rept 10\n"
"1: b 1b\n"
".endr\n"
#else
- "b barebox_arm_reset_vector\n"
+ "b 2f\n"
"1: b 1b\n"
"1: b 1b\n"
"1: b 1b\n"
@@ -74,6 +74,14 @@ static inline void barebox_arm_head(void)
".rept 8\n"
".word 0x55555555\n"
".endr\n"
+ "2:\n"
+ );
+}
+static inline void barebox_arm_head(void)
+{
+ __barebox_arm_head();
+ __asm__ __volatile__ (
+ "b barebox_arm_reset_vector\n"
);
}
#endif
diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
index cd8decfccd..622bd13622 100644
--- a/arch/arm/include/asm/barebox-arm.h
+++ b/arch/arm/include/asm/barebox-arm.h
@@ -54,6 +54,8 @@ static inline void arm_fixup_vectors(void)
}
#endif
+void *barebox_arm_boot_dtb(void);
+
/*
* For relocatable binaries find a suitable start address for the
* relocated binary. Beginning at the memory end substract the reserved
@@ -77,4 +79,8 @@ static inline unsigned long arm_barebox_image_place(unsigned long endmem)
return endmem;
}
+#define ENTRY_FUNCTION(name) \
+ void __naked __section(.text_head_entry_##name) \
+ name
+
#endif /* _BAREBOX_ARM_H_ */
diff --git a/arch/arm/pbl/zbarebox.lds.S b/arch/arm/lib/pbl.lds.S
index 6b23bbe79c..1eae8298ee 100644
--- a/arch/arm/pbl/zbarebox.lds.S
+++ b/arch/arm/lib/pbl.lds.S
@@ -26,7 +26,6 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
-ENTRY(pbl_start)
SECTIONS
{
#ifdef CONFIG_PBL_RELOCATABLE
@@ -87,6 +86,12 @@ SECTIONS
}
__piggydata_end = .;
- _barebox_image_size = __piggydata_end - (TEXT_BASE - SZ_2M);
+ . = ALIGN(4);
+ .image_end : {
+ KEEP(*(.image_end))
+ }
+ __image_end = .;
+
+ _barebox_image_size = __image_end - (TEXT_BASE - SZ_2M);
_barebox_pbl_size = __bss_start - (TEXT_BASE - SZ_2M);
}
diff --git a/arch/arm/lib/runtime-offset.S b/arch/arm/lib/runtime-offset.S
index 15bf4149b7..f10c4c8469 100644
--- a/arch/arm/lib/runtime-offset.S
+++ b/arch/arm/lib/runtime-offset.S
@@ -42,6 +42,9 @@ ld_var_entry __dynsym_end
ld_var_entry _barebox_image_size
ld_var_entry __bss_start
ld_var_entry __bss_stop
+#ifdef __PBL__
+ld_var_entry __image_end
+#endif
1:
ldr r1, =__ld_var_base
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 644c05eca0..b80e88564d 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -67,6 +67,7 @@ config BOARDINFO
choice
prompt "Select boot mode"
depends on !ARCH_IMX_INTERNAL_BOOT_USE_IMXIMAGE
+ depends on !HAVE_PBL_MULTI_IMAGES
help
i.MX processors support two different boot modes. With the internal
boot mode the boot medium contains a header describing the image to
@@ -329,6 +330,7 @@ config MACH_PCM038
select DRIVER_SPI_IMX
select MFD_MC13XXX
select HAVE_DEFAULT_ENVIRONMENT_NEW
+ select HAVE_PBL_MULTI_IMAGES
help
Say Y here if you are using Phytec's phyCORE-i.MX27 (pcm038) equipped
with a Freescale i.MX27 Processor
diff --git a/arch/arm/pbl/Makefile b/arch/arm/pbl/Makefile
index 3f50f77bc0..8923a704e1 100644
--- a/arch/arm/pbl/Makefile
+++ b/arch/arm/pbl/Makefile
@@ -29,9 +29,12 @@ endif
zbarebox-common := $(barebox-pbl-common) $(obj)/$(piggy_o)
zbarebox-lds := $(obj)/zbarebox.lds
+$(zbarebox-lds): $(obj)/../lib/pbl.lds.S FORCE
+ $(call if_changed_dep,cpp_lds_S)
+
quiet_cmd_zbarebox__ ?= LD $@
cmd_zbarebox__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_zbarebox) -o $@ \
- -T $(zbarebox-lds) \
+ -e pbl_start -T $(zbarebox-lds) \
--start-group $(zbarebox-common) --end-group \
$(filter-out $(zbarebox-lds) $(zbarebox-common) FORCE ,$^)
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index ffe063e0b7..03ae599279 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -1,4 +1,5 @@
config OFTREE
+ select DTC
bool
config OFTREE_MEM_GENERIC
diff --git a/images/Makefile b/images/Makefile
new file mode 100644
index 0000000000..925a98793b
--- /dev/null
+++ b/images/Makefile
@@ -0,0 +1,124 @@
+#
+# barebox image generation Makefile
+#
+# This Makefile generates multiple images from a common barebox image
+# and different pbl (pre bootloader) images. Optionally the result is
+# encapsulated in SoC (or SoC boot type) specific image formats.
+#
+# The basic idea here is that we generate a single barebox main binary. This
+# is compressed and prepended with a self extractor, generated as barebox.x.
+# barebox.x is then prepended with different board specific pbls. The pbls
+# are generally named after their entrypoints. So a pcm038 specific pbl will
+# generate the following files:
+#
+# start_imx27_pcm038.pbl - The ELF file, linked with the entrypoint start_imx27_pcm038
+# start_imx27_pcm038.pblb - The raw binary of the above.
+# start_imx27_pcm038.pblx - The pblb appended with barebox.x
+# start_imx27_pcm038.pbl.map - The linker map file
+# start_imx27_pcm038.pbl.s - the disassembled ELF, generated with:
+# make images/start_imx27_pcm038.pbl.s
+#
+# Example Makefile snippets for the i.MX51 babbage board (for readability in opposite
+# order):
+#
+## image-$(CONFIG_MACH_FREESCALE_MX51_PDK) += barebox-imx51-babbage.img
+#
+# For CONFIG_MACH_FREESCALE_MX51_PDK build barebox-imx51-babbage.img
+#
+## FILE_barebox-imx51-babbage.img = start_imx51_babbage.pblx.imximg
+#
+# barebox-imx51-babbage.img should be generated (copied) from
+# start_imx51_babbage.pblx.imximg. This copy process is only done so that we
+# can generate images with a sane name. So what we really need for this
+# board is a i.MX specific image, a .imximg
+#
+## imximage-$(CONFIG_MACH_FREESCALE_MX51_PDK) += start_imx51_babbage.pblx.imximg
+## CFG_start_imx51_babbage.pblx.imximg = $(board)/freescale-mx51-pdk/flash-header.imxcfg
+#
+# The .imximg can be generated from a .pblx using a rule specified in Makefile.imx.
+# The configfile needed for this image is specified with CFG_<filename> = <configfile>
+#
+## pblx-$(CONFIG_MACH_FREESCALE_MX51_PDK) += start_imx51_babbage
+#
+# For this image we need a pblx (self extracting barebox binary) with
+# start_imx51_babbage as entrypoint. start_imx51_babbage will be used
+# both as entrypoint and as filename
+#
+
+quiet_cmd_objcopy_bin = OBJCOPYB $@
+ cmd_objcopy_bin = $(OBJCOPY) -O binary $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
+
+pbl-lds := $(obj)/pbl.lds
+extra-y += $(pbl-lds)
+
+$(pbl-lds): $(obj)/../arch/$(ARCH)/lib/pbl.lds.S FORCE
+ $(call if_changed_dep,cpp_lds_S)
+
+quiet_cmd_elf__ ?= LD $@
+ cmd_elf__ ?= $(LD) $(LDFLAGS) -static --gc-sections -pie \
+ -e $(2) -Map $@.map $(LDFLAGS_$(@F)) -o $@ \
+ -T $(pbl-lds) \
+ --start-group $(barebox-pbl-common) --end-group
+
+PBL_CPPFLAGS += -fdata-sections -ffunction-sections
+
+$(obj)/%.pbl: $(pbl-lds) $(barebox-pbl-common) FORCE
+ $(call if_changed,elf__,$(*F))
+
+$(obj)/%.pblb: $(obj)/%.pbl FORCE
+ $(call if_changed,objcopy_bin,$(*F))
+
+quiet_cmd_pblx ?= PBLX $@
+ cmd_pblx ?= cat $(obj)/$(patsubst %.pblx,%.pblb,$(2)) > $@; \
+ $(call size_append, $(obj)/barebox.x) >> $@; \
+ cat $(obj)/barebox.x >> $@
+
+$(obj)/%.pblx: $(obj)/%.pblb $(obj)/barebox.x FORCE
+ $(call if_changed,pblx,$(@F))
+
+$(obj)/%.s: $(obj)/% FORCE
+ $(call if_changed,disasm)
+
+suffix_$(CONFIG_IMAGE_COMPRESSION_GZIP) = gzip
+suffix_$(CONFIG_IMAGE_COMPRESSION_LZO) = lzo
+suffix_$(CONFIG_IMAGE_COMPRESSION_NONE) = shipped
+
+# barebox.z - compressed barebox binary
+# ----------------------------------------------------------------
+$(obj)/barebox.z: $(obj)/../barebox.bin FORCE
+ $(call if_changed,$(suffix_y))
+
+quiet_cmd_selfextract = COMP $@
+ cmd_selfextract = cat $(obj)/start_uncompress.pblb > $@; \
+ $(call size_append, $<) >> $@; \
+ cat $< >> $@
+
+pblx-y += start_uncompress
+# barebox.x - self extracting barebox binary
+# ----------------------------------------------------------------
+$(obj)/barebox.x: $(obj)/barebox.z $(obj)/start_uncompress.pblb FORCE
+ $(call if_changed,selfextract)
+
+# %.img - create a copy from another file
+# ----------------------------------------------------------------
+.SECONDEXPANSION:
+$(obj)/%.img: $(obj)/$$(FILE_$$(@F))
+ $(Q)if [ -z $(FILE_$(@F)) ]; then echo "FILE_$(@F) empty!"; false; fi
+ $(call if_changed,shipped)
+
+include $(srctree)/images/Makefile.imx
+
+targets += $(image-y) pbl.lds barebox.x barebox.z
+targets += $(patsubst %,%.pblx,$(pblx-y))
+targets += $(patsubst %,%.pblb,$(pblx-y))
+targets += $(patsubst %,%.pbl,$(pblx-y))
+targets += $(patsubst %,%.s,$(pblx-y))
+targets += $(imximage-y)
+
+SECONDARY: $(addprefix $(obj)/,$(targets))
+
+images: $(addprefix $(obj)/, $(image-y)) FORCE
+ @echo "images built:\n" $(patsubst %,%\\n,$(image-y))
+
+clean-files := *.pbl *.pblb *.pblx *.map start_*.imximg *.img barebox.z
+clean-files += pbl.lds
diff --git a/images/Makefile.imx b/images/Makefile.imx
new file mode 100644
index 0000000000..63347297eb
--- /dev/null
+++ b/images/Makefile.imx
@@ -0,0 +1,15 @@
+#
+# barebox image generation Makefile for i.MX images
+#
+
+# %.imximg - convert into i.MX image
+# ----------------------------------------------------------------
+$(obj)/%.imximg: $(obj)/% FORCE
+ $(call if_changed,imx_image)
+
+board = $(srctree)/arch/$(ARCH)/boards
+
+# ----------------------- i.MX27 based boards ---------------------------
+pblx-$(CONFIG_MACH_PCM038) += start_imx27_pcm038
+FILE_barebox-phytec-phycore-imx27.img = start_imx27_pcm038.pblx
+image-$(CONFIG_MACH_PCM038) += barebox-phytec-phycore-imx27.img
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index 5492aa4d98..984f8b606b 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -6,6 +6,7 @@ extern char __bss_start[], __bss_stop[];
extern char _sdata[], _edata[];
extern char __bare_init_start[], __bare_init_end[];
extern char _end[];
+extern char __image_end[];
extern void *_barebox_image_size;
extern void *_barebox_bare_init_size;
extern void *_barebox_pbl_size;
diff --git a/pbl/Kconfig b/pbl/Kconfig
index 5c7f62eefe..a37c97610a 100644
--- a/pbl/Kconfig
+++ b/pbl/Kconfig
@@ -1,6 +1,9 @@
config HAVE_PBL_IMAGE
bool
+config HAVE_PBL_MULTI_IMAGES
+ bool
+
config HAVE_IMAGE_COMPRESSION
bool
@@ -8,6 +11,19 @@ config PBL_IMAGE
bool "Pre-Bootloader image"
depends on HAVE_PBL_IMAGE
+config PBL_MULTI_IMAGES
+ bool
+ select PBL_IMAGE
+ select PBL_RELOCATABLE
+ depends on HAVE_PBL_MULTI_IMAGES
+ default y
+
+config PBL_SINGLE_IMAGE
+ bool
+ depends on PBL_IMAGE
+ depends on !HAVE_PBL_MULTI_IMAGES
+ default y
+
config PBL_FORCE_PIGGYDATA_COPY
bool
help
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 0b56dcc218..307412f8d7 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -329,4 +329,4 @@ $(obj)/%.S: $(obj)/%.dcd
$(call cmd,imximage_S_dcd)
quiet_cmd_imx_image = IMX-IMG $@
- cmd_imx_image = $(obj)/scripts/imx/imx-image -b -c $(CFG_$(@F)) -f $< -o $@
+ cmd_imx_image = $(objtree)/scripts/imx/imx-image -b -c $(CFG_$(@F)) -f $< -o $@