* [PATCH 1/6] ARM: make cpu architecture detection available as static inline function
2013-03-04 20:03 [PATCH] ARM: Add relocatable binary support Sascha Hauer
@ 2013-03-04 20:03 ` Sascha Hauer
2013-03-04 20:46 ` Alexander Aring
2013-03-04 20:03 ` [PATCH 2/6] ARM: add early mmu cache flush function and use it in setup_c Sascha Hauer
` (4 subsequent siblings)
5 siblings, 1 reply; 15+ messages in thread
From: Sascha Hauer @ 2013-03-04 20:03 UTC (permalink / raw)
To: barebox
When we have multi cpu support compiled in we need the cpu architecture
early so that we can pick the correct cacheflush function. Make it available
as static inline function and add a comment above it that this function
normally should not be used.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/cpu/cpu.c | 34 +-----------------------------
arch/arm/include/asm/system_info.h | 43 ++++++++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+), 33 deletions(-)
diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c
index 5f697d7..f2e698d 100644
--- a/arch/arm/cpu/cpu.c
+++ b/arch/arm/cpu/cpu.c
@@ -148,45 +148,13 @@ postcore_initcall(execute_init);
#endif
#ifdef ARM_MULTIARCH
-static int __get_cpu_architecture(void)
-{
- int cpu_arch;
-
- if ((read_cpuid_id() & 0x0008f000) == 0) {
- cpu_arch = CPU_ARCH_UNKNOWN;
- } else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
- cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
- } else if ((read_cpuid_id() & 0x00080000) == 0x00000000) {
- cpu_arch = (read_cpuid_id() >> 16) & 7;
- if (cpu_arch)
- cpu_arch += CPU_ARCH_ARMv3;
- } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
- unsigned int mmfr0;
-
- /* Revised CPUID format. Read the Memory Model Feature
- * Register 0 and check for VMSAv7 or PMSAv7 */
- asm("mrc p15, 0, %0, c0, c1, 4"
- : "=r" (mmfr0));
- if ((mmfr0 & 0x0000000f) >= 0x00000003 ||
- (mmfr0 & 0x000000f0) >= 0x00000030)
- cpu_arch = CPU_ARCH_ARMv7;
- else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
- (mmfr0 & 0x000000f0) == 0x00000020)
- cpu_arch = CPU_ARCH_ARMv6;
- else
- cpu_arch = CPU_ARCH_UNKNOWN;
- } else
- cpu_arch = CPU_ARCH_UNKNOWN;
-
- return cpu_arch;
-}
int __cpu_architecture;
int __pure cpu_architecture(void)
{
if(__cpu_architecture == CPU_ARCH_UNKNOWN)
- __cpu_architecture = __get_cpu_architecture();
+ __cpu_architecture = arm_early_get_cpu_architecture();
return __cpu_architecture;
}
diff --git a/arch/arm/include/asm/system_info.h b/arch/arm/include/asm/system_info.h
index 56ebb11..50769ec 100644
--- a/arch/arm/include/asm/system_info.h
+++ b/arch/arm/include/asm/system_info.h
@@ -110,8 +110,51 @@
#ifndef __ASSEMBLY__
#ifdef ARM_MULTIARCH
+/*
+ * Early version to get the ARM cpu architecture. Only needed during
+ * early startup when the C environment is not yet fully initialized.
+ * Normally you should use cpu_architecture() instead.
+ */
+static inline int arm_early_get_cpu_architecture(void)
+{
+ int cpu_arch;
+
+ if ((read_cpuid_id() & 0x0008f000) == 0) {
+ cpu_arch = CPU_ARCH_UNKNOWN;
+ } else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
+ cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
+ } else if ((read_cpuid_id() & 0x00080000) == 0x00000000) {
+ cpu_arch = (read_cpuid_id() >> 16) & 7;
+ if (cpu_arch)
+ cpu_arch += CPU_ARCH_ARMv3;
+ } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
+ unsigned int mmfr0;
+
+ /* Revised CPUID format. Read the Memory Model Feature
+ * Register 0 and check for VMSAv7 or PMSAv7 */
+ asm("mrc p15, 0, %0, c0, c1, 4"
+ : "=r" (mmfr0));
+ if ((mmfr0 & 0x0000000f) >= 0x00000003 ||
+ (mmfr0 & 0x000000f0) >= 0x00000030)
+ cpu_arch = CPU_ARCH_ARMv7;
+ else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
+ (mmfr0 & 0x000000f0) == 0x00000020)
+ cpu_arch = CPU_ARCH_ARMv6;
+ else
+ cpu_arch = CPU_ARCH_UNKNOWN;
+ } else
+ cpu_arch = CPU_ARCH_UNKNOWN;
+
+ return cpu_arch;
+}
+
extern int __pure cpu_architecture(void);
#else
+static inline int __pure arm_early_get_cpu_architecture(void)
+{
+ return ARM_ARCH;
+}
+
static inline int __pure cpu_architecture(void)
{
return ARM_ARCH;
--
1.8.2.rc2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 1/6] ARM: make cpu architecture detection available as static inline function
2013-03-04 20:03 ` [PATCH 1/6] ARM: make cpu architecture detection available as static inline function Sascha Hauer
@ 2013-03-04 20:46 ` Alexander Aring
2013-03-05 10:34 ` Sascha Hauer
0 siblings, 1 reply; 15+ messages in thread
From: Alexander Aring @ 2013-03-04 20:46 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
Hi,
On Mon, Mar 04, 2013 at 09:03:04PM +0100, Sascha Hauer wrote:
> When we have multi cpu support compiled in we need the cpu architecture
> early so that we can pick the correct cacheflush function. Make it available
> as static inline function and add a comment above it that this function
> normally should not be used.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> arch/arm/cpu/cpu.c | 34 +-----------------------------
> arch/arm/include/asm/system_info.h | 43 ++++++++++++++++++++++++++++++++++++++
> 2 files changed, 44 insertions(+), 33 deletions(-)
>
> diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c
> index 5f697d7..f2e698d 100644
> --- a/arch/arm/cpu/cpu.c
> +++ b/arch/arm/cpu/cpu.c
> @@ -148,45 +148,13 @@ postcore_initcall(execute_init);
> #endif
>
> #ifdef ARM_MULTIARCH
> -static int __get_cpu_architecture(void)
> -{
> - int cpu_arch;
> -
> - if ((read_cpuid_id() & 0x0008f000) == 0) {
> - cpu_arch = CPU_ARCH_UNKNOWN;
> - } else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
> - cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
> - } else if ((read_cpuid_id() & 0x00080000) == 0x00000000) {
> - cpu_arch = (read_cpuid_id() >> 16) & 7;
> - if (cpu_arch)
> - cpu_arch += CPU_ARCH_ARMv3;
> - } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
> - unsigned int mmfr0;
> -
> - /* Revised CPUID format. Read the Memory Model Feature
> - * Register 0 and check for VMSAv7 or PMSAv7 */
> - asm("mrc p15, 0, %0, c0, c1, 4"
> - : "=r" (mmfr0));
> - if ((mmfr0 & 0x0000000f) >= 0x00000003 ||
> - (mmfr0 & 0x000000f0) >= 0x00000030)
> - cpu_arch = CPU_ARCH_ARMv7;
> - else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
> - (mmfr0 & 0x000000f0) == 0x00000020)
> - cpu_arch = CPU_ARCH_ARMv6;
> - else
> - cpu_arch = CPU_ARCH_UNKNOWN;
> - } else
> - cpu_arch = CPU_ARCH_UNKNOWN;
> -
> - return cpu_arch;
> -}
>
> int __cpu_architecture;
>
> int __pure cpu_architecture(void)
> {
> if(__cpu_architecture == CPU_ARCH_UNKNOWN)
> - __cpu_architecture = __get_cpu_architecture();
> + __cpu_architecture = arm_early_get_cpu_architecture();
>
> return __cpu_architecture;
> }
> diff --git a/arch/arm/include/asm/system_info.h b/arch/arm/include/asm/system_info.h
> index 56ebb11..50769ec 100644
> --- a/arch/arm/include/asm/system_info.h
> +++ b/arch/arm/include/asm/system_info.h
> @@ -110,8 +110,51 @@
> #ifndef __ASSEMBLY__
>
> #ifdef ARM_MULTIARCH
> +/*
> + * Early version to get the ARM cpu architecture. Only needed during
> + * early startup when the C environment is not yet fully initialized.
> + * Normally you should use cpu_architecture() instead.
> + */
> +static inline int arm_early_get_cpu_architecture(void)
> +{
> + int cpu_arch;
> +
> + if ((read_cpuid_id() & 0x0008f000) == 0) {
> + cpu_arch = CPU_ARCH_UNKNOWN;
> + } else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
> + cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
> + } else if ((read_cpuid_id() & 0x00080000) == 0x00000000) {
> + cpu_arch = (read_cpuid_id() >> 16) & 7;
> + if (cpu_arch)
> + cpu_arch += CPU_ARCH_ARMv3;
I know... it's only a movement, but is cpu += CPU_ARCH_ARMv3 correct
here? All other has only a assignment.
> + } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
> + unsigned int mmfr0;
> +
> + /* Revised CPUID format. Read the Memory Model Feature
> + * Register 0 and check for VMSAv7 or PMSAv7 */
> + asm("mrc p15, 0, %0, c0, c1, 4"
> + : "=r" (mmfr0));
> + if ((mmfr0 & 0x0000000f) >= 0x00000003 ||
> + (mmfr0 & 0x000000f0) >= 0x00000030)
> + cpu_arch = CPU_ARCH_ARMv7;
> + else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
> + (mmfr0 & 0x000000f0) == 0x00000020)
> + cpu_arch = CPU_ARCH_ARMv6;
> + else
> + cpu_arch = CPU_ARCH_UNKNOWN;
> + } else
> + cpu_arch = CPU_ARCH_UNKNOWN;
> +
> + return cpu_arch;
> +}
> +
> extern int __pure cpu_architecture(void);
> #else
> +static inline int __pure arm_early_get_cpu_architecture(void)
> +{
> + return ARM_ARCH;
> +}
> +
> static inline int __pure cpu_architecture(void)
> {
> return ARM_ARCH;
> --
> 1.8.2.rc2
>
>
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 1/6] ARM: make cpu architecture detection available as static inline function
2013-03-04 20:46 ` Alexander Aring
@ 2013-03-05 10:34 ` Sascha Hauer
0 siblings, 0 replies; 15+ messages in thread
From: Sascha Hauer @ 2013-03-05 10:34 UTC (permalink / raw)
To: Alexander Aring; +Cc: barebox
On Mon, Mar 04, 2013 at 09:46:56PM +0100, Alexander Aring wrote:
> Hi,
>
> > +/*
> > + * Early version to get the ARM cpu architecture. Only needed during
> > + * early startup when the C environment is not yet fully initialized.
> > + * Normally you should use cpu_architecture() instead.
> > + */
> > +static inline int arm_early_get_cpu_architecture(void)
> > +{
> > + int cpu_arch;
> > +
> > + if ((read_cpuid_id() & 0x0008f000) == 0) {
> > + cpu_arch = CPU_ARCH_UNKNOWN;
> > + } else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
> > + cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
> > + } else if ((read_cpuid_id() & 0x00080000) == 0x00000000) {
> > + cpu_arch = (read_cpuid_id() >> 16) & 7;
> > + if (cpu_arch)
> > + cpu_arch += CPU_ARCH_ARMv3;
>
> I know... it's only a movement, but is cpu += CPU_ARCH_ARMv3 correct
> here? All other has only a assignment.
This particular line is present in the Kernel since the pre-git days, so
I assume it's correct ;)
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 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 2/6] ARM: add early mmu cache flush function and use it in setup_c
2013-03-04 20:03 [PATCH] ARM: Add relocatable binary support Sascha Hauer
2013-03-04 20:03 ` [PATCH 1/6] ARM: make cpu architecture detection available as static inline function Sascha Hauer
@ 2013-03-04 20:03 ` Sascha Hauer
2013-03-04 20:03 ` [PATCH 3/6] ARM: provide accessor functions for linker variables Sascha Hauer
` (3 subsequent siblings)
5 siblings, 0 replies; 15+ messages in thread
From: Sascha Hauer @ 2013-03-04 20:03 UTC (permalink / raw)
To: barebox
Since recently with MMU_EARLY support it may happen that setup_c
runs with data caches enabled, so we have to make sure the caches
are flushed before we jump to the new binary.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/cpu/cache.c | 33 +++++++++++++++++++++++++++++++++
arch/arm/cpu/setupc.S | 3 +++
arch/arm/include/asm/cache.h | 8 ++++++++
3 files changed, 44 insertions(+)
diff --git a/arch/arm/cpu/cache.c b/arch/arm/cpu/cache.c
index 1254609..95c8338 100644
--- a/arch/arm/cpu/cache.c
+++ b/arch/arm/cpu/cache.c
@@ -101,3 +101,36 @@ int arm_set_cache_functions(void)
return 0;
}
+
+/*
+ * Early function to flush the caches. This is for use when the
+ * C environment is not yet fully initialized.
+ */
+void arm_early_mmu_cache_flush(void)
+{
+ switch (arm_early_get_cpu_architecture()) {
+#ifdef CONFIG_CPU_32v4T
+ case CPU_ARCH_ARMv4T:
+ v4_mmu_cache_flush();
+ return;
+#endif
+#ifdef CONFIG_CPU_32v5
+ case CPU_ARCH_ARMv5:
+ case CPU_ARCH_ARMv5T:
+ case CPU_ARCH_ARMv5TE:
+ case CPU_ARCH_ARMv5TEJ:
+ v5_mmu_cache_flush();
+ return;
+#endif
+#ifdef CONFIG_CPU_32v6
+ case CPU_ARCH_ARMv6:
+ v6_mmu_cache_flush();
+ return;
+#endif
+#ifdef CONFIG_CPU_32v7
+ case CPU_ARCH_ARMv7:
+ v7_mmu_cache_flush();
+ return;
+#endif
+ }
+}
diff --git a/arch/arm/cpu/setupc.S b/arch/arm/cpu/setupc.S
index 9a8d54c..d0de87d 100644
--- a/arch/arm/cpu/setupc.S
+++ b/arch/arm/cpu/setupc.S
@@ -26,6 +26,9 @@ ENTRY(setup_c)
ldr r2, =__bss_stop
sub r2, r2, r0
bl memset /* clear bss */
+#ifdef CONFIG_MMU
+ bl arm_early_mmu_cache_flush
+#endif
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 /* flush icache */
add lr, r5, r4 /* adjust return address to new location */
diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
index d5877ff..e5621eb 100644
--- a/arch/arm/include/asm/cache.h
+++ b/arch/arm/include/asm/cache.h
@@ -8,4 +8,12 @@ static inline void flush_icache(void)
int arm_set_cache_functions(void);
+#ifdef CONFIG_MMU
+void arm_early_mmu_cache_flush(void);
+#else
+static inline void arm_early_mmu_cache_flush(void)
+{
+}
+#endif
+
#endif
--
1.8.2.rc2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 3/6] ARM: provide accessor functions for linker variables
2013-03-04 20:03 [PATCH] ARM: Add relocatable binary support Sascha Hauer
2013-03-04 20:03 ` [PATCH 1/6] ARM: make cpu architecture detection available as static inline function Sascha Hauer
2013-03-04 20:03 ` [PATCH 2/6] ARM: add early mmu cache flush function and use it in setup_c Sascha Hauer
@ 2013-03-04 20:03 ` Sascha Hauer
2013-03-04 20:03 ` [PATCH 4/6] ARM boards: Use accessor functions to access " Sascha Hauer
` (2 subsequent siblings)
5 siblings, 0 replies; 15+ messages in thread
From: Sascha Hauer @ 2013-03-04 20:03 UTC (permalink / raw)
To: barebox
With relocatable binaries the linker is not able to supply absolute
addresses. These only get available when the relocation function is
being run. Since for early initialization we need some variables
before relocation, we supply them relatively to some known address
in the binary. This means that the variables have to be converted
to absolute addresses during runtime.
This patch adds a C macro and an assembly macro to calculate the
variables during runtime.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/include/asm/sections.h | 33 +++++++++++++++++++++++++++++++++
arch/arm/lib/runtime-offset.S | 32 ++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+)
diff --git a/arch/arm/include/asm/sections.h b/arch/arm/include/asm/sections.h
index 2b8c516..8c7bc8c 100644
--- a/arch/arm/include/asm/sections.h
+++ b/arch/arm/include/asm/sections.h
@@ -1 +1,34 @@
+#ifndef __ASM_SECTIONS_H
+#define __ASM_SECTIONS_H
+
+#ifndef __ASSEMBLY__
#include <asm-generic/sections.h>
+
+/*
+ * Access a linker supplied variable. Use this if your code might not be running
+ * at the address it is linked at.
+ */
+#define ld_var(name) ({ \
+ unsigned long __ld_var_##name(void); \
+ __ld_var_##name(); \
+})
+
+#else
+
+/*
+ * Access a linker supplied variable, assembler macro version
+ */
+.macro ld_var name, reg, scratch
+ 1000:
+ ldr \reg, 1001f
+ ldr \scratch, =1000b
+ add \reg, \reg, \scratch
+ b 1002f
+ 1001:
+ .word \name - 1000b
+ 1002:
+.endm
+
+#endif
+
+#endif /* __ASM_SECTIONS_H */
diff --git a/arch/arm/lib/runtime-offset.S b/arch/arm/lib/runtime-offset.S
index ffa668c..15bf414 100644
--- a/arch/arm/lib/runtime-offset.S
+++ b/arch/arm/lib/runtime-offset.S
@@ -1,6 +1,8 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
+.section ".text_bare_init","ax"
+
/*
* Get the offset between the link address and the address
* we are currently running at.
@@ -15,3 +17,33 @@ THUMB( subs r0, r0, #1)
linkadr:
.word get_runtime_offset
ENDPROC(get_runtime_offset)
+
+.globl __ld_var_base
+__ld_var_base:
+
+/*
+ * Functions to calculate selected linker supplied variables during runtime.
+ * This is needed for relocatable binaries when the linker variables are
+ * needed before finxing up the relocations.
+ */
+.macro ld_var_entry name
+ ENTRY(__ld_var_\name)
+ ldr r0, __\name
+ b 1f
+ __\name: .word \name - __ld_var_base
+ ENDPROC(__ld_var_\name)
+.endm
+
+ld_var_entry _text
+ld_var_entry __rel_dyn_start
+ld_var_entry __rel_dyn_end
+ld_var_entry __dynsym_start
+ld_var_entry __dynsym_end
+ld_var_entry _barebox_image_size
+ld_var_entry __bss_start
+ld_var_entry __bss_stop
+
+1:
+ ldr r1, =__ld_var_base
+ adds r0, r0, r1
+ mov pc, lr
--
1.8.2.rc2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 4/6] ARM boards: Use accessor functions to access linker variables
2013-03-04 20:03 [PATCH] ARM: Add relocatable binary support Sascha Hauer
` (2 preceding siblings ...)
2013-03-04 20:03 ` [PATCH 3/6] ARM: provide accessor functions for linker variables Sascha Hauer
@ 2013-03-04 20:03 ` Sascha Hauer
2013-03-04 20:03 ` [PATCH 5/6] ARN: fixup vector addresses for relocatable binaries Sascha Hauer
2013-03-04 20:03 ` [PATCH 6/6] ARM: Add relocatable binary support Sascha Hauer
5 siblings, 0 replies; 15+ messages in thread
From: Sascha Hauer @ 2013-03-04 20:03 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/boards/friendlyarm-tiny210/lowlevel.c | 3 ++-
arch/arm/mach-imx/external-nand-boot.c | 27 +++++++++++++++-----------
drivers/mtd/nand/nand_s3c24xx.c | 2 +-
3 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/arch/arm/boards/friendlyarm-tiny210/lowlevel.c b/arch/arm/boards/friendlyarm-tiny210/lowlevel.c
index 1da7ba8..3bd1379 100644
--- a/arch/arm/boards/friendlyarm-tiny210/lowlevel.c
+++ b/arch/arm/boards/friendlyarm-tiny210/lowlevel.c
@@ -67,7 +67,8 @@ void __bare_init barebox_arm_reset_vector(void)
s5p_init_dram_bank_ddr2(S5P_DMC0_BASE, 0x20E00323, 0, 0);
- if (! s5p_irom_load_mmc((void*)TEXT_BASE - 16, 1, (barebox_image_size + 16 + 511) / 512))
+ if (! s5p_irom_load_mmc((void*)TEXT_BASE - 16, 1,
+ (ld_var(_barebox_image_size) + 16 + 511) / 512))
while (1) { } /* hang */
/* Jump to SDRAM */
diff --git a/arch/arm/mach-imx/external-nand-boot.c b/arch/arm/mach-imx/external-nand-boot.c
index 73c4ccd..3ac1132 100644
--- a/arch/arm/mach-imx/external-nand-boot.c
+++ b/arch/arm/mach-imx/external-nand-boot.c
@@ -292,7 +292,7 @@ int __bare_init imx_barebox_boot_nand_external(unsigned long nfc_base)
return 0;
src = (unsigned int *)nfc_base;
- trg = (unsigned int *)_text;
+ trg = (unsigned int *)ld_var(_text);
/* Move ourselves out of NFC SRAM */
for (i = 0; i < 0x800 / sizeof(int); i++)
@@ -313,8 +313,9 @@ void __bare_init __noreturn imx21_barebox_boot_nand_external(void)
unsigned long nfc_base = MX21_NFC_BASE_ADDR;
if (imx_barebox_boot_nand_external(nfc_base)) {
- jump_sdram(nfc_base - (unsigned long)_text);
- imx_nand_load_image((void *)_text, barebox_image_size);
+ jump_sdram(nfc_base - ld_var(_text));
+ imx_nand_load_image((void *)ld_var(_text),
+ ld_var(barebox_image_size));
}
imx21_barebox_entry(0);
@@ -327,8 +328,9 @@ void __bare_init __noreturn imx25_barebox_boot_nand_external(void)
unsigned long nfc_base = MX25_NFC_BASE_ADDR;
if (imx_barebox_boot_nand_external(nfc_base)) {
- jump_sdram(nfc_base - (unsigned long)_text);
- imx_nand_load_image((void *)_text, barebox_image_size);
+ jump_sdram(nfc_base - ld_var(_text));
+ imx_nand_load_image((void *)ld_var(_text),
+ ld_var(_barebox_image_size));
}
imx25_barebox_entry(0);
@@ -341,8 +343,9 @@ void __bare_init __noreturn imx27_barebox_boot_nand_external(void)
unsigned long nfc_base = MX27_NFC_BASE_ADDR;
if (imx_barebox_boot_nand_external(nfc_base)) {
- jump_sdram(nfc_base - (unsigned long)_text);
- imx_nand_load_image((void *)_text, barebox_image_size);
+ jump_sdram(nfc_base - ld_var(_text));
+ imx_nand_load_image((void *)ld_var(_text),
+ ld_var(_barebox_image_size));
}
imx27_barebox_entry(0);
@@ -355,8 +358,9 @@ void __bare_init __noreturn imx31_barebox_boot_nand_external(void)
unsigned long nfc_base = MX31_NFC_BASE_ADDR;
if (imx_barebox_boot_nand_external(nfc_base)) {
- jump_sdram(nfc_base - (unsigned long)_text);
- imx_nand_load_image((void *)_text, barebox_image_size);
+ jump_sdram(nfc_base - ld_var(_text));
+ imx_nand_load_image((void *)ld_var(_text),
+ ld_var(_barebox_image_size));
}
imx31_barebox_entry(0);
@@ -369,8 +373,9 @@ void __bare_init __noreturn imx35_barebox_boot_nand_external(void)
unsigned long nfc_base = MX35_NFC_BASE_ADDR;
if (imx_barebox_boot_nand_external(nfc_base)) {
- jump_sdram(nfc_base - (unsigned long)_text);
- imx_nand_load_image((void *)_text, barebox_image_size);
+ jump_sdram(nfc_base - ld_var(_text));
+ imx_nand_load_image((void *)ld_var(_text),
+ ld_var(_barebox_image_size));
}
imx35_barebox_entry(0);
diff --git a/drivers/mtd/nand/nand_s3c24xx.c b/drivers/mtd/nand/nand_s3c24xx.c
index fef9432..c2e41a9 100644
--- a/drivers/mtd/nand/nand_s3c24xx.c
+++ b/drivers/mtd/nand/nand_s3c24xx.c
@@ -607,7 +607,7 @@ void __nand_boot_init s3c24x0_nand_load_image(void *dest, int size, int page)
void __nand_boot_init nand_boot(void)
{
void *dest = _text;
- int size = barebox_image_size;
+ int size = ld_var(_barebox_image_size);
int page = 0;
s3c24x0_nand_load_image(dest, size, page);
--
1.8.2.rc2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 5/6] ARN: fixup vector addresses for relocatable binaries
2013-03-04 20:03 [PATCH] ARM: Add relocatable binary support Sascha Hauer
` (3 preceding siblings ...)
2013-03-04 20:03 ` [PATCH 4/6] ARM boards: Use accessor functions to access " Sascha Hauer
@ 2013-03-04 20:03 ` Sascha Hauer
2013-03-04 20:03 ` [PATCH 6/6] ARM: Add relocatable binary support Sascha Hauer
5 siblings, 0 replies; 15+ messages in thread
From: Sascha Hauer @ 2013-03-04 20:03 UTC (permalink / raw)
To: barebox
With relocatable binaries the vector addresses cannot be supplied by
the linker. This adds support for fixing them up during runtime.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/cpu/exceptions.S | 55 +++++++++++++++++++++++++++++++++-----
arch/arm/cpu/mmu.c | 2 ++
arch/arm/include/asm/barebox-arm.h | 8 ++++++
arch/arm/include/asm/mmu.h | 1 -
4 files changed, 59 insertions(+), 7 deletions(-)
diff --git a/arch/arm/cpu/exceptions.S b/arch/arm/cpu/exceptions.S
index 4185bd1..6d87cd2 100644
--- a/arch/arm/cpu/exceptions.S
+++ b/arch/arm/cpu/exceptions.S
@@ -1,4 +1,5 @@
#include <config.h>
+#include <linux/linkage.h>
#include <asm-generic/memory_layout.h>
/*
@@ -137,16 +138,58 @@ fiq:
bad_save_user_regs
bl do_fiq
+#ifdef CONFIG_RELOCATABLE
+/*
+ * With relocatable binary support the runtime exception vectors do not match
+ * the addresses in the binary. We have to fix them up during runtime
+ */
+ENTRY(arm_fixup_vectors)
+ ldr r0, =undefined_instruction
+ ldr r1, =_undefined_instruction
+ str r0, [r1]
+ ldr r0, =software_interrupt
+ ldr r1, =_software_interrupt
+ str r0, [r1]
+ ldr r0, =prefetch_abort
+ ldr r1, =_prefetch_abort
+ str r0, [r1]
+ ldr r0, =data_abort
+ ldr r1, =_data_abort
+ str r0, [r1]
+ ldr r0, =irq
+ ldr r1, =_irq
+ str r0, [r1]
+ ldr r0, =fiq
+ ldr r1, =_fiq
+ str r0, [r1]
+ bx lr
+ENDPROC(arm_fixup_vectors)
+#endif
+
.section .text_exceptions
+.globl extable
+extable:
1: b 1b /* barebox_arm_reset_vector */
#ifdef CONFIG_ARM_EXCEPTIONS
- ldr pc, =undefined_instruction /* undefined instruction */
- ldr pc, =software_interrupt /* software interrupt (SWI) */
- ldr pc, =prefetch_abort /* prefetch abort */
- ldr pc, =data_abort /* data abort */
+ ldr pc, _undefined_instruction /* undefined instruction */
+ ldr pc, _software_interrupt /* software interrupt (SWI) */
+ ldr pc, _prefetch_abort /* prefetch abort */
+ ldr pc, _data_abort /* data abort */
1: b 1b /* (reserved) */
- ldr pc, =irq /* irq (interrupt) */
- ldr pc, =fiq /* fiq (fast interrupt) */
+ ldr pc, _irq /* irq (interrupt) */
+ ldr pc, _fiq /* fiq (fast interrupt) */
+.globl _undefined_instruction
+_undefined_instruction: .word undefined_instruction
+.globl _software_interrupt
+_software_interrupt: .word software_interrupt
+.globl _prefetch_abort
+_prefetch_abort: .word prefetch_abort
+.globl _data_abort
+_data_abort: .word data_abort
+.globl _irq
+_irq: .word irq
+.globl _fiq
+_fiq: .word fiq
#else
1: b 1b /* undefined instruction */
1: b 1b /* software interrupt (SWI) */
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 219f50a..34fe5c3 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -247,6 +247,8 @@ static void vectors_init(void)
exc = arm_create_pte(0x0);
}
+ arm_fixup_vectors();
+
vectors = xmemalign(PAGE_SIZE, PAGE_SIZE);
memset(vectors, 0, PAGE_SIZE);
memcpy(vectors, __exceptions_start, __exceptions_stop - __exceptions_start);
diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
index 9c10e36..f051fe3 100644
--- a/arch/arm/include/asm/barebox-arm.h
+++ b/arch/arm/include/asm/barebox-arm.h
@@ -42,4 +42,12 @@ uint32_t get_runtime_offset(void);
void setup_c(void);
void __noreturn barebox_arm_entry(uint32_t membase, uint32_t memsize, uint32_t boarddata);
+#ifdef CONFIG_RELOCATABLE
+void arm_fixup_vectors(void);
+#else
+static inline void arm_fixup_vectors(void)
+{
+}
+#endif
+
#endif /* _BAREBOX_ARM_H_ */
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index f32cea6..4234979 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -122,4 +122,3 @@ void __dma_flush_range(unsigned long, unsigned long);
void __dma_inv_range(unsigned long, unsigned long);
#endif /* __ASM_MMU_H */
-
--
1.8.2.rc2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 6/6] ARM: Add relocatable binary support
2013-03-04 20:03 [PATCH] ARM: Add relocatable binary support Sascha Hauer
` (4 preceding siblings ...)
2013-03-04 20:03 ` [PATCH 5/6] ARN: fixup vector addresses for relocatable binaries Sascha Hauer
@ 2013-03-04 20:03 ` Sascha Hauer
2013-03-04 20:10 ` Alexander Shiyan
2013-03-04 20:53 ` Alexander Aring
5 siblings, 2 replies; 15+ messages in thread
From: Sascha Hauer @ 2013-03-04 20:03 UTC (permalink / raw)
To: barebox
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@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@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;
+
+ /* 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;
+
+ arm_early_mmu_cache_flush();
+ flush_icache();
+}
diff --git a/arch/arm/cpu/setupc.S b/arch/arm/cpu/setupc.S
index d0de87d..7fd5d01 100644
--- a/arch/arm/cpu/setupc.S
+++ b/arch/arm/cpu/setupc.S
@@ -1,4 +1,5 @@
#include <linux/linkage.h>
+#include <asm/sections.h>
.section .text.setupc
@@ -35,3 +36,61 @@ ENTRY(setup_c)
pop {r4, r5}
mov pc, lr
ENDPROC(setup_c)
+
+#ifdef CONFIG_RELOCATABLE
+/*
+ * void relocate_to_adr(unsigned long targetadr)
+ *
+ * Copy binary to targetadr, relocate code, clear bss and continue
+ * executing at new address.
+ */
+.section .text.relocate_to_adr
+ENTRY(relocate_to_adr)
+ /* r0: target address */
+ push {r3, r4, r5, r6, r7, r8}
+ mov r7, lr
+
+ mov r6, r0
+
+ bl get_runtime_offset
+
+ mov r5, r0
+
+ ld_var _text, r0, r4
+ mov r8, r0
+
+ sub r1, r0, r5 /* r1: from address */
+
+ cmp r1, r6 /* already at correct address? */
+ beq 1f /* yes, skip copy to new address */
+
+ ld_var __bss_start, r2, r4
+
+ sub r2, r2, r0 /* r2: size */
+ mov r0, r6 /* r0: target */
+
+ add r7, r7, r0 /* adjust return address */
+ sub r7, r7, r1 /* lr += offset */
+
+ bl memcpy /* copy binary */
+
+#ifdef CONFIG_MMU
+ bl arm_early_mmu_cache_flush
+#endif
+ mov r0,#0
+ mcr p15, 0, r0, c7, c5, 0 /* flush icache */
+
+ ldr r0,=1f
+ sub r0, r0, r8
+ add r0, r0, r6
+ mov pc, r0 /* jump to relocated address */
+1:
+ bl relocate_to_current_adr /* relocate binary */
+
+ mov lr, r7
+
+ pop {r3, r4, r5, r6, r7, r8}
+ mov pc, lr
+
+ENDPROC(relocate_to_adr)
+#endif
diff --git a/arch/arm/cpu/start-pbl.c b/arch/arm/cpu/start-pbl.c
index 91bc8fe..6f03c4a 100644
--- a/arch/arm/cpu/start-pbl.c
+++ b/arch/arm/cpu/start-pbl.c
@@ -55,9 +55,13 @@ static noinline __noreturn void __barebox_arm_entry(uint32_t membase,
uint32_t pg_start, pg_end, pg_len;
void __noreturn (*barebox)(uint32_t, uint32_t, uint32_t);
uint32_t endmem = membase + memsize;
+ unsigned long barebox_base;
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();
@@ -65,8 +69,13 @@ static noinline __noreturn void __barebox_arm_entry(uint32_t membase,
pg_end = (uint32_t)&input_data_end - offset;
pg_len = pg_end - pg_start;
+ if (IS_ENABLED(CONFIG_RELOCATABLE))
+ barebox_base = arm_barebox_image_place(membase + memsize);
+ else
+ barebox_base = TEXT_BASE;
+
if (offset && (IS_ENABLED(CONFIG_PBL_FORCE_PIGGYDATA_COPY) ||
- region_overlap(pg_start, pg_len, TEXT_BASE, pg_len * 4))) {
+ region_overlap(pg_start, pg_len, barebox_base, pg_len * 4))) {
/*
* copy piggydata binary to its link address
*/
@@ -86,14 +95,15 @@ static noinline __noreturn void __barebox_arm_entry(uint32_t membase,
free_mem_ptr = endmem;
free_mem_end_ptr = free_mem_ptr + SZ_128K;
- pbl_barebox_uncompress((void*)TEXT_BASE, (void *)pg_start, pg_len);
+ pbl_barebox_uncompress((void*)barebox_base, (void *)pg_start, pg_len);
+ arm_early_mmu_cache_flush();
flush_icache();
if (IS_ENABLED(CONFIG_THUMB2_BAREBOX))
- barebox = (void *)(TEXT_BASE + 1);
+ barebox = (void *)(barebox_base + 1);
else
- barebox = (void *)TEXT_BASE;
+ barebox = (void *)barebox_base;
barebox(membase, memsize, boarddata);
}
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index cd34d9c..7c2bcd0 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -37,6 +37,11 @@ static noinline __noreturn void __start(uint32_t membase, uint32_t memsize,
unsigned long endmem = membase + memsize;
unsigned long malloc_start, malloc_end;
+ if (IS_ENABLED(CONFIG_RELOCATABLE)) {
+ unsigned long barebox_base = arm_barebox_image_place(endmem);
+ relocate_to_adr(barebox_base);
+ }
+
setup_c();
arm_stack_top = endmem;
diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
index f051fe3..76e31a0 100644
--- a/arch/arm/include/asm/barebox-arm.h
+++ b/arch/arm/include/asm/barebox-arm.h
@@ -26,6 +26,7 @@
#define _BAREBOX_ARM_H_
#include <sizes.h>
+#include <asm-generic/memory_layout.h>
/* cpu/.../cpu.c */
int cleanup_before_linux(void);
@@ -40,6 +41,8 @@ void board_init_lowlevel(void);
uint32_t get_runtime_offset(void);
void setup_c(void);
+void relocate_to_current_adr(void);
+void relocate_to_adr(unsigned long target);
void __noreturn barebox_arm_entry(uint32_t membase, uint32_t memsize, uint32_t boarddata);
#ifdef CONFIG_RELOCATABLE
@@ -50,4 +53,27 @@ static inline void arm_fixup_vectors(void)
}
#endif
+/*
+ * For relocatable binaries find a suitable start address for the
+ * relocated binary. Beginning at the memory end substract the reserved
+ * space and round down a bit at the end. This is used by the pbl to
+ * extract the image to a suitable place so that the uncompressed image
+ * does not have to copy itself to another place. Also it's used by
+ * the uncompressed image to relocate itself to the same place.
+ */
+static inline unsigned long arm_barebox_image_place(unsigned long endmem)
+{
+ endmem -= STACK_SIZE;
+ endmem -= SZ_32K; /* ttb */
+ endmem -= SZ_128K; /* early malloc */
+ endmem -= SZ_1M; /* place for barebox image */
+
+ /*
+ * round down to make translating the objdump easier
+ */
+ endmem &= ~(SZ_1M - 1);
+
+ return endmem;
+}
+
#endif /* _BAREBOX_ARM_H_ */
diff --git a/arch/arm/lib/barebox.lds.S b/arch/arm/lib/barebox.lds.S
index e5aee8c..abdd69e 100644
--- a/arch/arm/lib/barebox.lds.S
+++ b/arch/arm/lib/barebox.lds.S
@@ -25,7 +25,11 @@ OUTPUT_ARCH(arm)
ENTRY(start)
SECTIONS
{
+#ifdef CONFIG_RELOCATABLE
+ . = 0x0;
+#else
. = TEXT_BASE;
+#endif
#ifndef CONFIG_PBL_IMAGE
PRE_IMAGE
@@ -88,7 +92,20 @@ SECTIONS
__usymtab : { BAREBOX_SYMS }
__usymtab_end = .;
+ .rel.dyn : {
+ __rel_dyn_start = .;
+ *(.rel*)
+ __rel_dyn_end = .;
+ }
+
+ .dynsym : {
+ __dynsym_start = .;
+ *(.dynsym)
+ __dynsym_end = .;
+ }
+
_edata = .;
+
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss*) }
diff --git a/arch/arm/pbl/Makefile b/arch/arm/pbl/Makefile
index 6eeee73..3f50f77 100644
--- a/arch/arm/pbl/Makefile
+++ b/arch/arm/pbl/Makefile
@@ -23,6 +23,9 @@ $(obj)/zbarebox.S: $(obj)/zbarebox FORCE
PBL_CPPFLAGS += -fdata-sections -ffunction-sections
LDFLAGS_zbarebox := -Map $(obj)/zbarebox.map
LDFLAGS_zbarebox += -static --gc-sections
+ifdef CONFIG_PBL_RELOCATABLE
+LDFLAGS_zbarebox += -pie
+endif
zbarebox-common := $(barebox-pbl-common) $(obj)/$(piggy_o)
zbarebox-lds := $(obj)/zbarebox.lds
diff --git a/arch/arm/pbl/zbarebox.lds.S b/arch/arm/pbl/zbarebox.lds.S
index 564b3c6..6b23bbe 100644
--- a/arch/arm/pbl/zbarebox.lds.S
+++ b/arch/arm/pbl/zbarebox.lds.S
@@ -29,7 +29,11 @@ OUTPUT_ARCH(arm)
ENTRY(pbl_start)
SECTIONS
{
+#ifdef CONFIG_PBL_RELOCATABLE
+ . = 0x0;
+#else
. = TEXT_BASE - SZ_2M;
+#endif
PRE_IMAGE
@@ -58,6 +62,18 @@ SECTIONS
. = ALIGN(4);
.data : { *(.data*) }
+ .rel.dyn : {
+ __rel_dyn_start = .;
+ *(.rel*)
+ __rel_dyn_end = .;
+ }
+
+ .dynsym : {
+ __dynsym_start = .;
+ *(.dynsym)
+ __dynsym_end = .;
+ }
+
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss*) }
diff --git a/common/Kconfig b/common/Kconfig
index 3a55e01..92a6fdf 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -243,7 +243,7 @@ config KALLSYMS
This is useful to print a nice backtrace when an exception occurs.
config RELOCATABLE
- depends on PPC
+ depends on PPC || ARM
bool "generate relocatable barebox binary"
help
A non relocatable barebox binary will run at it's compiled in
diff --git a/pbl/Kconfig b/pbl/Kconfig
index 39752cc..5c7f62e 100644
--- a/pbl/Kconfig
+++ b/pbl/Kconfig
@@ -18,6 +18,16 @@ config PBL_FORCE_PIGGYDATA_COPY
if PBL_IMAGE
+config PBL_RELOCATABLE
+ depends on ARM
+ bool "relocatable pbl image"
+ help
+ Generate a pbl 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.
+ This option only inflluences the PBL image. See RELOCATABLE to also make
+ the real image relocatable.
+
config IMAGE_COMPRESSION
bool
depends on HAVE_IMAGE_COMPRESSION
--
1.8.2.rc2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 6/6] ARM: Add relocatable binary support
2013-03-04 20:03 ` [PATCH 6/6] ARM: Add relocatable binary support Sascha Hauer
@ 2013-03-04 20:10 ` Alexander Shiyan
2013-03-04 20:19 ` Sascha Hauer
2013-03-04 20:53 ` Alexander Aring
1 sibling, 1 reply; 15+ messages in thread
From: Alexander Shiyan @ 2013-03-04 20:10 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
> 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@pengutronix.de>
...
Hello.
I just suggest put this new stuff under EXPERIMENTAL condition.
Thanks.
---
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 6/6] ARM: Add relocatable binary support
2013-03-04 20:10 ` Alexander Shiyan
@ 2013-03-04 20:19 ` Sascha Hauer
2013-03-05 4:32 ` Re[2]: " Alexander Shiyan
0 siblings, 1 reply; 15+ messages in thread
From: Sascha Hauer @ 2013-03-04 20:19 UTC (permalink / raw)
To: Alexander Shiyan; +Cc: barebox
On Tue, Mar 05, 2013 at 12:10:02AM +0400, Alexander Shiyan 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@pengutronix.de>
> ...
>
> Hello.
>
> I just suggest put this new stuff under EXPERIMENTAL condition.
> Thanks.
I'm unsure this makes sense. In the kernel currently 388 options depend
on EXPERIMENTAL and 433 out of 438 defconfigs have EXPERIMENTAL enabled.
This recently led to the discussion whether this option should be
removed from the Kernel.
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 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re[2]: [PATCH 6/6] ARM: Add relocatable binary support
2013-03-04 20:19 ` Sascha Hauer
@ 2013-03-05 4:32 ` Alexander Shiyan
2013-03-05 7:25 ` Sascha Hauer
0 siblings, 1 reply; 15+ messages in thread
From: Alexander Shiyan @ 2013-03-05 4:32 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
> On Tue, Mar 05, 2013 at 12:10:02AM +0400, Alexander Shiyan 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@pengutronix.de>
> > ...
> >
> > Hello.
> >
> > I just suggest put this new stuff under EXPERIMENTAL condition.
> > Thanks.
>
> I'm unsure this makes sense. In the kernel currently 388 options depend
> on EXPERIMENTAL and 433 out of 438 defconfigs have EXPERIMENTAL enabled.
> This recently led to the discussion whether this option should be
> removed from the Kernel.
OK.
One more thing. You are introduce "RELOCATABLE" symbol in arm/Kconfig,
but symbol with same name is already exist in common/Kconfig. On
my opinion this is no so good.
Thanks.
---
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 6/6] ARM: Add relocatable binary support
2013-03-05 4:32 ` Re[2]: " Alexander Shiyan
@ 2013-03-05 7:25 ` Sascha Hauer
0 siblings, 0 replies; 15+ messages in thread
From: Sascha Hauer @ 2013-03-05 7:25 UTC (permalink / raw)
To: Alexander Shiyan; +Cc: barebox
On Tue, Mar 05, 2013 at 08:32:11AM +0400, Alexander Shiyan wrote:
> > On Tue, Mar 05, 2013 at 12:10:02AM +0400, Alexander Shiyan 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@pengutronix.de>
> > > ...
> > >
> > > Hello.
> > >
> > > I just suggest put this new stuff under EXPERIMENTAL condition.
> > > Thanks.
> >
> > I'm unsure this makes sense. In the kernel currently 388 options depend
> > on EXPERIMENTAL and 433 out of 438 defconfigs have EXPERIMENTAL enabled.
> > This recently led to the discussion whether this option should be
> > removed from the Kernel.
>
> OK.
>
> One more thing. You are introduce "RELOCATABLE" symbol in arm/Kconfig,
> but symbol with same name is already exist in common/Kconfig. On
> my opinion this is no so good.
Indeed. This was not intentional. I removed it from arch/arm/Kconfig
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 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 6/6] ARM: Add relocatable binary support
2013-03-04 20:03 ` [PATCH 6/6] ARM: Add relocatable binary support Sascha Hauer
2013-03-04 20:10 ` Alexander Shiyan
@ 2013-03-04 20:53 ` Alexander Aring
2013-03-05 10:46 ` Sascha Hauer
1 sibling, 1 reply; 15+ messages in thread
From: Alexander Aring @ 2013-03-04 20:53 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
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@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@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. :-)
> +
> + arm_early_mmu_cache_flush();
> + flush_icache();
> +}
> diff --git a/arch/arm/cpu/setupc.S b/arch/arm/cpu/setupc.S
> index d0de87d..7fd5d01 100644
> --- a/arch/arm/cpu/setupc.S
> +++ b/arch/arm/cpu/setupc.S
> @@ -1,4 +1,5 @@
> #include <linux/linkage.h>
> +#include <asm/sections.h>
>
> .section .text.setupc
>
> @@ -35,3 +36,61 @@ ENTRY(setup_c)
> pop {r4, r5}
> mov pc, lr
> ENDPROC(setup_c)
> +
> +#ifdef CONFIG_RELOCATABLE
> +/*
> + * void relocate_to_adr(unsigned long targetadr)
> + *
> + * Copy binary to targetadr, relocate code, clear bss and continue
> + * executing at new address.
> + */
> +.section .text.relocate_to_adr
> +ENTRY(relocate_to_adr)
> + /* r0: target address */
> + push {r3, r4, r5, r6, r7, r8}
> + mov r7, lr
> +
> + mov r6, r0
> +
> + bl get_runtime_offset
> +
> + mov r5, r0
> +
> + ld_var _text, r0, r4
> + mov r8, r0
> +
> + sub r1, r0, r5 /* r1: from address */
> +
> + cmp r1, r6 /* already at correct address? */
> + beq 1f /* yes, skip copy to new address */
> +
> + ld_var __bss_start, r2, r4
> +
> + sub r2, r2, r0 /* r2: size */
> + mov r0, r6 /* r0: target */
> +
> + add r7, r7, r0 /* adjust return address */
> + sub r7, r7, r1 /* lr += offset */
> +
> + bl memcpy /* copy binary */
> +
> +#ifdef CONFIG_MMU
> + bl arm_early_mmu_cache_flush
> +#endif
> + mov r0,#0
> + mcr p15, 0, r0, c7, c5, 0 /* flush icache */
> +
> + ldr r0,=1f
> + sub r0, r0, r8
> + add r0, r0, r6
> + mov pc, r0 /* jump to relocated address */
> +1:
Is this label ever used? I don't see it.
> + bl relocate_to_current_adr /* relocate binary */
> +
> + mov lr, r7
> +
> + pop {r3, r4, r5, r6, r7, r8}
> + mov pc, lr
> +
> +ENDPROC(relocate_to_adr)
> +#endif
> diff --git a/arch/arm/cpu/start-pbl.c b/arch/arm/cpu/start-pbl.c
> index 91bc8fe..6f03c4a 100644
> --- a/arch/arm/cpu/start-pbl.c
> +++ b/arch/arm/cpu/start-pbl.c
> @@ -55,9 +55,13 @@ static noinline __noreturn void __barebox_arm_entry(uint32_t membase,
> uint32_t pg_start, pg_end, pg_len;
> void __noreturn (*barebox)(uint32_t, uint32_t, uint32_t);
> uint32_t endmem = membase + memsize;
> + unsigned long barebox_base;
>
> 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();
>
> @@ -65,8 +69,13 @@ static noinline __noreturn void __barebox_arm_entry(uint32_t membase,
> pg_end = (uint32_t)&input_data_end - offset;
> pg_len = pg_end - pg_start;
>
> + if (IS_ENABLED(CONFIG_RELOCATABLE))
> + barebox_base = arm_barebox_image_place(membase + memsize);
> + else
> + barebox_base = TEXT_BASE;
> +
> if (offset && (IS_ENABLED(CONFIG_PBL_FORCE_PIGGYDATA_COPY) ||
> - region_overlap(pg_start, pg_len, TEXT_BASE, pg_len * 4))) {
> + region_overlap(pg_start, pg_len, barebox_base, pg_len * 4))) {
> /*
> * copy piggydata binary to its link address
> */
> @@ -86,14 +95,15 @@ static noinline __noreturn void __barebox_arm_entry(uint32_t membase,
> free_mem_ptr = endmem;
> free_mem_end_ptr = free_mem_ptr + SZ_128K;
>
> - pbl_barebox_uncompress((void*)TEXT_BASE, (void *)pg_start, pg_len);
> + pbl_barebox_uncompress((void*)barebox_base, (void *)pg_start, pg_len);
>
> + arm_early_mmu_cache_flush();
> flush_icache();
>
> if (IS_ENABLED(CONFIG_THUMB2_BAREBOX))
> - barebox = (void *)(TEXT_BASE + 1);
> + barebox = (void *)(barebox_base + 1);
> else
> - barebox = (void *)TEXT_BASE;
> + barebox = (void *)barebox_base;
>
> barebox(membase, memsize, boarddata);
> }
> diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
> index cd34d9c..7c2bcd0 100644
> --- a/arch/arm/cpu/start.c
> +++ b/arch/arm/cpu/start.c
> @@ -37,6 +37,11 @@ static noinline __noreturn void __start(uint32_t membase, uint32_t memsize,
> unsigned long endmem = membase + memsize;
> unsigned long malloc_start, malloc_end;
>
> + if (IS_ENABLED(CONFIG_RELOCATABLE)) {
> + unsigned long barebox_base = arm_barebox_image_place(endmem);
> + relocate_to_adr(barebox_base);
> + }
> +
> setup_c();
>
> arm_stack_top = endmem;
> diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
> index f051fe3..76e31a0 100644
> --- a/arch/arm/include/asm/barebox-arm.h
> +++ b/arch/arm/include/asm/barebox-arm.h
> @@ -26,6 +26,7 @@
> #define _BAREBOX_ARM_H_
>
> #include <sizes.h>
> +#include <asm-generic/memory_layout.h>
>
> /* cpu/.../cpu.c */
> int cleanup_before_linux(void);
> @@ -40,6 +41,8 @@ void board_init_lowlevel(void);
> uint32_t get_runtime_offset(void);
>
> void setup_c(void);
> +void relocate_to_current_adr(void);
> +void relocate_to_adr(unsigned long target);
> void __noreturn barebox_arm_entry(uint32_t membase, uint32_t memsize, uint32_t boarddata);
>
> #ifdef CONFIG_RELOCATABLE
> @@ -50,4 +53,27 @@ static inline void arm_fixup_vectors(void)
> }
> #endif
>
> +/*
> + * For relocatable binaries find a suitable start address for the
> + * relocated binary. Beginning at the memory end substract the reserved
> + * space and round down a bit at the end. This is used by the pbl to
> + * extract the image to a suitable place so that the uncompressed image
> + * does not have to copy itself to another place. Also it's used by
> + * the uncompressed image to relocate itself to the same place.
> + */
> +static inline unsigned long arm_barebox_image_place(unsigned long endmem)
> +{
> + endmem -= STACK_SIZE;
> + endmem -= SZ_32K; /* ttb */
> + endmem -= SZ_128K; /* early malloc */
> + endmem -= SZ_1M; /* place for barebox image */
> +
> + /*
> + * round down to make translating the objdump easier
> + */
> + endmem &= ~(SZ_1M - 1);
> +
> + return endmem;
> +}
> +
> #endif /* _BAREBOX_ARM_H_ */
> diff --git a/arch/arm/lib/barebox.lds.S b/arch/arm/lib/barebox.lds.S
> index e5aee8c..abdd69e 100644
> --- a/arch/arm/lib/barebox.lds.S
> +++ b/arch/arm/lib/barebox.lds.S
> @@ -25,7 +25,11 @@ OUTPUT_ARCH(arm)
> ENTRY(start)
> SECTIONS
> {
> +#ifdef CONFIG_RELOCATABLE
> + . = 0x0;
> +#else
> . = TEXT_BASE;
> +#endif
>
> #ifndef CONFIG_PBL_IMAGE
> PRE_IMAGE
> @@ -88,7 +92,20 @@ SECTIONS
> __usymtab : { BAREBOX_SYMS }
> __usymtab_end = .;
>
> + .rel.dyn : {
> + __rel_dyn_start = .;
> + *(.rel*)
> + __rel_dyn_end = .;
> + }
> +
> + .dynsym : {
> + __dynsym_start = .;
> + *(.dynsym)
> + __dynsym_end = .;
> + }
> +
> _edata = .;
> +
> . = ALIGN(4);
> __bss_start = .;
> .bss : { *(.bss*) }
> diff --git a/arch/arm/pbl/Makefile b/arch/arm/pbl/Makefile
> index 6eeee73..3f50f77 100644
> --- a/arch/arm/pbl/Makefile
> +++ b/arch/arm/pbl/Makefile
> @@ -23,6 +23,9 @@ $(obj)/zbarebox.S: $(obj)/zbarebox FORCE
> PBL_CPPFLAGS += -fdata-sections -ffunction-sections
> LDFLAGS_zbarebox := -Map $(obj)/zbarebox.map
> LDFLAGS_zbarebox += -static --gc-sections
> +ifdef CONFIG_PBL_RELOCATABLE
> +LDFLAGS_zbarebox += -pie
> +endif
> zbarebox-common := $(barebox-pbl-common) $(obj)/$(piggy_o)
> zbarebox-lds := $(obj)/zbarebox.lds
>
> diff --git a/arch/arm/pbl/zbarebox.lds.S b/arch/arm/pbl/zbarebox.lds.S
> index 564b3c6..6b23bbe 100644
> --- a/arch/arm/pbl/zbarebox.lds.S
> +++ b/arch/arm/pbl/zbarebox.lds.S
> @@ -29,7 +29,11 @@ OUTPUT_ARCH(arm)
> ENTRY(pbl_start)
> SECTIONS
> {
> +#ifdef CONFIG_PBL_RELOCATABLE
> + . = 0x0;
> +#else
> . = TEXT_BASE - SZ_2M;
> +#endif
>
> PRE_IMAGE
>
> @@ -58,6 +62,18 @@ SECTIONS
> . = ALIGN(4);
> .data : { *(.data*) }
>
> + .rel.dyn : {
> + __rel_dyn_start = .;
> + *(.rel*)
> + __rel_dyn_end = .;
> + }
> +
> + .dynsym : {
> + __dynsym_start = .;
> + *(.dynsym)
> + __dynsym_end = .;
> + }
> +
> . = ALIGN(4);
> __bss_start = .;
> .bss : { *(.bss*) }
> diff --git a/common/Kconfig b/common/Kconfig
> index 3a55e01..92a6fdf 100644
> --- a/common/Kconfig
> +++ b/common/Kconfig
> @@ -243,7 +243,7 @@ config KALLSYMS
> This is useful to print a nice backtrace when an exception occurs.
>
> config RELOCATABLE
> - depends on PPC
> + depends on PPC || ARM
> bool "generate relocatable barebox binary"
> help
> A non relocatable barebox binary will run at it's compiled in
> diff --git a/pbl/Kconfig b/pbl/Kconfig
> index 39752cc..5c7f62e 100644
> --- a/pbl/Kconfig
> +++ b/pbl/Kconfig
> @@ -18,6 +18,16 @@ config PBL_FORCE_PIGGYDATA_COPY
>
> if PBL_IMAGE
>
> +config PBL_RELOCATABLE
> + depends on ARM
> + bool "relocatable pbl image"
> + help
> + Generate a pbl 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.
> + This option only inflluences the PBL image. See RELOCATABLE to also make
> + the real image relocatable.
> +
> config IMAGE_COMPRESSION
> bool
> depends on HAVE_IMAGE_COMPRESSION
> --
> 1.8.2.rc2
>
>
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 6/6] ARM: Add relocatable binary support
2013-03-04 20:53 ` Alexander Aring
@ 2013-03-05 10:46 ` Sascha Hauer
0 siblings, 0 replies; 15+ messages in thread
From: Sascha Hauer @ 2013-03-05 10:46 UTC (permalink / raw)
To: Alexander Aring; +Cc: barebox
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@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@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 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread