[PATCH 6/6] ARM: Add relocatable binary support
Sascha Hauer
s.hauer at pengutronix.de
Tue Mar 5 05:46:30 EST 2013
On Mon, Mar 04, 2013 at 09:53:22PM +0100, Alexander Aring wrote:
> Hi,
>
> On Mon, Mar 04, 2013 at 09:03:09PM +0100, Sascha Hauer wrote:
> > For making the same binary executable on different SoCs which have
> > different DRAM addresses we have to be independent of the compile
> > time link address.
> >
> > This patch adds relocatable binary support for the ARM architecture.
> > With this two new functions are available. relocate_to_current_adr
> > will fixup the binary to continue executing from the current position.
> > relocate_to_adr will copy the binary to a given address, fixup the
> > binary and continue executing from there.
> >
> > For the PBL and the real image relocatable support can be enabled
> > independently. This is done to (hopefully) better cope with setups
> > where the PBL runs from SRAM or ROM and the real binary does not.
> >
> > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > ---
> > arch/arm/Kconfig | 9 +++++
> > arch/arm/Makefile | 4 +++
> > arch/arm/cpu/Makefile | 3 ++
> > arch/arm/cpu/common.c | 68 ++++++++++++++++++++++++++++++++++++++
> > arch/arm/cpu/setupc.S | 59 +++++++++++++++++++++++++++++++++
> > arch/arm/cpu/start-pbl.c | 18 +++++++---
> > arch/arm/cpu/start.c | 5 +++
> > arch/arm/include/asm/barebox-arm.h | 26 +++++++++++++++
> > arch/arm/lib/barebox.lds.S | 17 ++++++++++
> > arch/arm/pbl/Makefile | 3 ++
> > arch/arm/pbl/zbarebox.lds.S | 16 +++++++++
> > common/Kconfig | 2 +-
> > pbl/Kconfig | 10 ++++++
> > 13 files changed, 235 insertions(+), 5 deletions(-)
> > create mode 100644 arch/arm/cpu/common.c
> >
> > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > index 7ac134e..efe0773 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -12,6 +12,15 @@ config ARM_LINUX
> > default y
> > depends on CMD_BOOTZ || CMD_BOOTU || CMD_BOOTM
> >
> > +config RELOCATABLE
> > + prompt "relocatable binary"
> > + bool
> > + help
> > + Generate a binary which can relocate itself during startup to run
> > + on different addresses. This is useful if your memory layout is not
> > + known during compile time. Selecting this will result in a slightly
> > + bigger image.
> > +
> > config HAVE_MACH_ARM_HEAD
> > bool
> >
> > diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> > index b98d6b8..5125b87 100644
> > --- a/arch/arm/Makefile
> > +++ b/arch/arm/Makefile
> > @@ -181,6 +181,10 @@ CPPFLAGS += -fdata-sections -ffunction-sections
> > LDFLAGS_barebox += -static --gc-sections
> > endif
> >
> > +ifdef CONFIG_RELOCATABLE
> > +LDFLAGS_barebox += -pie
> > +endif
> > +
> > ifdef CONFIG_IMAGE_COMPRESSION
> > KBUILD_BINARY := arch/arm/pbl/zbarebox.bin
> > KBUILD_TARGET := zbarebox.bin
> > diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
> > index 44410ee..5935e1c 100644
> > --- a/arch/arm/cpu/Makefile
> > +++ b/arch/arm/cpu/Makefile
> > @@ -21,3 +21,6 @@ pbl-$(CONFIG_CPU_32v7) += cache-armv7.o
> > obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
> >
> > pbl-y += start-pbl.o setupc.o
> > +
> > +obj-y += common.o
> > +pbl-y += common.o
> > diff --git a/arch/arm/cpu/common.c b/arch/arm/cpu/common.c
> > new file mode 100644
> > index 0000000..856ddf2
> > --- /dev/null
> > +++ b/arch/arm/cpu/common.c
> > @@ -0,0 +1,68 @@
> > +/*
> > + * Copyright (c) 2010 Sascha Hauer <s.hauer at pengutronix.de>, Pengutronix
> > + *
> > + * 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.
> > + *
> > + */
> > +
> > +#include <common.h>
> > +#include <init.h>
> > +#include <sizes.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>
> > +
> > +/*
> > + * relocate binary to the currently running address
> > + */
> > +void relocate_to_current_adr(void)
> > +{
> > + uint32_t offset;
> > + uint32_t *dstart, *dend, *dynsym;
> > + uint32_t *dynend;
>
> Some nitpick... we can do this in one line maybe with fixup and type.
>
> > +
> > + /* Get offset between linked address and runtime address */
> > + offset = get_runtime_offset();
> > +
> > + dstart = (void *)(ld_var(__rel_dyn_start) - offset);
> > + dend = (void *)(ld_var(__rel_dyn_end) - offset);
> > +
> > + dynsym = (void *)(ld_var(__dynsym_start) - offset);
> > + dynend = (void *)(ld_var(__dynsym_end) - offset);
> > +
> > + while (dstart < dend) {
> > + uint32_t *fixup = (uint32_t *)(*dstart - offset);
> > + uint32_t type = *(dstart + 1);
> > +
> > + if ((type & 0xff) == 0x17) {
> > + *fixup = *fixup - offset;
> > + } else {
> > + int index = type >> 8;
> > + uint32_t r = dynsym[index * 4 + 1];
> > +
> > + *fixup = *fixup + r - offset;
> > + }
> > +
> > + *dstart -= offset;
> > + dstart += 2;
> > + }
> > +
> > + while (dynsym < dynend)
> > + *dynsym++ = 0;
>
> I think here we can use a memset. :-)
ok ;)
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
More information about the barebox
mailing list