[U-Boot] [RFC] [PATCH V2] arm: arm926ejs: use ELF relocations

Wolfgang Denk wd at denx.de
Tue Oct 5 10:02:49 CEST 2010


Dear Albert Aribaud,

In message <1286260287-1571-1-git-send-email-albert.aribaud at free.fr> you wrote:
> HISTORY:
> 
> V1	Initial patch
> V2	Rebased on latest mainline master
> 
> This patch is *not* a submission for master!

Tried with the following patch on armv7 (Beagle board):


diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index f411c0f..f5cd2db 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -69,22 +69,12 @@ _end_vect:
 _TEXT_BASE:
 	.word	TEXT_BASE
 
-#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
-.globl _armboot_start
-_armboot_start:
-	.word _start
-#endif
-
 /*
  * These are defined in the board-specific linker script.
+ * Subtracting _start from them lets the linker put their
+ * relative position in the executable instead of leaving
+ * them null.
  */
-.globl _bss_start
-_bss_start:
-	.word __bss_start
-
-.globl _bss_end
-_bss_end:
-	.word _end
 
 #ifdef CONFIG_USE_IRQ
 /* IRQ stack memory (calculated at run-time) */
@@ -98,35 +88,34 @@ FIQ_STACK_START:
 	.word 0x0badc0de
 #endif
 
-#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
 /* IRQ stack memory (calculated at run-time) + 8 bytes */
 .globl IRQ_STACK_START_IN
 IRQ_STACK_START_IN:
 	.word	0x0badc0de
 
-.globl _datarel_start
-_datarel_start:
-	.word __datarel_start
+.globl _bss_start_ofs
+_bss_start_ofs:
+	.word __bss_start - _start
 
-.globl _datarelrolocal_start
-_datarelrolocal_start:
-	.word __datarelrolocal_start
+.globl _bss_end_ofs
+_bss_end_ofs:
+	.word _end - _start
 
-.globl _datarellocal_start
-_datarellocal_start:
-	.word __datarellocal_start
+.globl _datarel_start_ofs
+_datarel_start_ofs:
+	.word __datarel_start - _start
 
-.globl _datarelro_start
-_datarelro_start:
-	.word __datarelro_start
+.globl _datarelrolocal_start_ofs
+_datarelrolocal_start_ofs:
+	.word __datarelrolocal_start - _start
 
-.globl _got_start
-_got_start:
-	.word __got_start
+.globl _datarellocal_start_ofs
+_datarellocal_start_ofs:
+	.word __datarellocal_start - _start
 
-.globl _got_end
-_got_end:
-	.word __got_end
+.globl _datarelro_start_ofs
+_datarelro_start_ofs:
+	.word __datarelro_start - _start
 
 /*
  * the actual reset code
@@ -198,9 +187,8 @@ stack_setup:
 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
 	adr	r0, _start
 	ldr	r2, _TEXT_BASE
-	ldr	r3, _bss_start
-	sub	r2, r3, r2		/* r2 <- size of armboot	    */
-	add	r2, r0, r2		/* r2 <- source end address	    */
+	ldr	r3, _bss_start_ofs
+	add	r2, r0, r3		/* r2 <- source end address	    */
 	cmp	r0, r6
 #ifndef CONFIG_PRELOADER
 	beq	jump_2_ram
@@ -213,34 +201,51 @@ copy_loop:
 	ble	copy_loop
 
 #ifndef CONFIG_PRELOADER
-	/* fix got entries */
-	ldr	r1, _TEXT_BASE
-	mov	r0, r7			/* reloc addr */
-	ldr	r2, _got_start		/* addr in Flash */
-	ldr	r3, _got_end		/* addr in Flash */
-	sub	r3, r3, r1
-	add	r3, r3, r0
-	sub	r2, r2, r1
-	add	r2, r2, r0
-
+	/*
+	 * fix .rel.dyn relocations
+	 */
+	ldr	r0, _TEXT_BASE		/* r0 <- Text base */
+	sub	r9, r7, r0		/* r9 <- relocation offset */
+	ldr	r10, _dynsym_start_ofs	/* r10 <- sym table ofs */
+	add	r10, r10, r0		/* r10 <- sym table in FLASH */
+	ldr	r2, _rel_dyn_start_ofs	/* r2 <- rel dyn start ofs */
+	add	r2, r2, r0		/* r2 <- rel dyn start in FLASH */
+	ldr	r3, _rel_dyn_end_ofs	/* r3 <- rel dyn end ofs */
+	add	r3, r3, r0		/* r3 <- rel dyn end in FLASH */
 fixloop:
-	ldr	r4, [r2]
-	sub	r4, r4, r1
-	add	r4, r4, r0
-	str	r4, [r2]
-	add	r2, r2, #4
+	ldr	r0, [r2]	/* r0 <- location to fix up, IN FLASH! */
+	add	r0, r9		/* r0 <- location to fix up in RAM */
+	ldr	r1, [r2, #4]
+	and	r8, r1, #0xff
+	cmp	r8, #23		/* relative fixup? */
+	beq	fixrel
+	cmp	r8, #2		/* absolute fixup? */
+	beq	fixabs
+	/* ignore unknown type of fixup */
+	b	fixnext
+fixabs:
+	/* absolute fix: set location to (offset) symbol value */
+	mov	r1, r1, LSR #4		/* r1 <- symbol index in .dynsym */
+	add	r1, r10, r1		/* r1 <- address of symbol in table */
+	ldr	r1, [r1, #4]		/* r1 <- symbol value */
+	add	r1, r9			/* r1 <- relocated sym addr */
+	b	fixnext
+fixrel:
+	/* relative fix: increase location by offset */
+	ldr	r1, [r0]
+	add	r1, r1, r9
+fixnext:
+	str	r1, [r0]
+	add	r2, r2, #8	/* each rel.dyn entry is 8 bytes */
 	cmp	r2, r3
-	bne	fixloop
+	ble	fixloop
 
 clear_bss:
-	ldr	r0, _bss_start
-	ldr	r1, _bss_end
-	ldr	r3, _TEXT_BASE		/* Text base */
-	mov	r4, r7			/* reloc addr */
-	sub	r0, r0, r3
-	add	r0, r0, r4
-	sub	r1, r1, r3
-	add	r1, r1, r4
+	adr	r2, _start
+	ldr	r0, _bss_start_ofs	/* find start of bss segment        */
+	add	r0, r0, r2
+	ldr	r1, _bss_end_ofs	/* stop here                        */
+	add	r1, r1, r2
 	mov	r2, #0x00000000		/* clear			    */
 
 clbss_l:str	r2, [r0]		/* clear loop...		    */
@@ -255,10 +260,10 @@ clbss_l:str	r2, [r0]		/* clear loop...		    */
  * initialization, now running from RAM.
  */
 jump_2_ram:
-	ldr	r0, _TEXT_BASE
-	ldr	r2, _board_init_r
-	sub	r2, r2, r0
-	add	r2, r2, r7	/* position from board_init_r in RAM */
+	ldr	r0, _board_init_r_ofs
+	adr	r1, _start
+	add	r0, r0, r1
+	add	lr, r0, r9
 	/* setup parameters for board_init_r */
 	mov	r0, r5		/* gd_t */
 	mov	r1, r7		/* dest_addr */
@@ -266,94 +271,15 @@ jump_2_ram:
 	mov	lr, r2
 	mov	pc, lr
 
-_board_init_r: .word board_init_r
-#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
-/*
- * the actual reset code
- */
-
-reset:
-	/*
-	 * set the cpu to SVC32 mode
-	 */
-	mrs	r0, cpsr
-	bic	r0, r0, #0x1f
-	orr	r0, r0, #0xd3
-	msr	cpsr,r0
-
-#if (CONFIG_OMAP34XX)
-	/* Copy vectors to mask ROM indirect addr */
-	adr	r0, _start		@ r0 <- current position of code
-	add	r0, r0, #4		@ skip reset vector
-	mov	r2, #64			@ r2 <- size to copy
-	add	r2, r0, r2		@ r2 <- source end address
-	mov	r1, #SRAM_OFFSET0	@ build vect addr
-	mov	r3, #SRAM_OFFSET1
-	add	r1, r1, r3
-	mov	r3, #SRAM_OFFSET2
-	add	r1, r1, r3
-next:
-	ldmia	r0!, {r3 - r10}		@ copy from source address [r0]
-	stmia	r1!, {r3 - r10}		@ copy to   target address [r1]
-	cmp	r0, r2			@ until source end address [r2]
-	bne	next			@ loop until equal */
-#if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_ONENAND_BOOT)
-	/* No need to copy/exec the clock code - DPLL adjust already done
-	 * in NAND/oneNAND Boot.
-	 */
-	bl	cpy_clk_code		@ put dpll adjust code behind vectors
-#endif /* NAND Boot */
-#endif
-	/* the mask ROM code should have PLL and others stable */
-#ifndef CONFIG_SKIP_LOWLEVEL_INIT
-	bl	cpu_init_crit
-#endif
-
-#ifndef CONFIG_SKIP_RELOCATE_UBOOT
-relocate:				@ relocate U-Boot to RAM
-	adr	r0, _start		@ r0 <- current position of code
-	ldr	r1, _TEXT_BASE		@ test if we run from flash or RAM
-	cmp	r0, r1			@ don't reloc during debug
-	beq	stack_setup
-
-	ldr	r2, _armboot_start
-	ldr	r3, _bss_start
-	sub	r2, r3, r2		@ r2 <- size of armboot
-	add	r2, r0, r2		@ r2 <- source end address
-
-copy_loop:				@ copy 32 bytes at a time
-	ldmia	r0!, {r3 - r10}		@ copy from source address [r0]
-	stmia	r1!, {r3 - r10}		@ copy to   target address [r1]
-	cmp	r0, r2			@ until source end addreee [r2]
-	ble	copy_loop
-#endif	/* CONFIG_SKIP_RELOCATE_UBOOT */
-
-	/* Set up the stack */
-stack_setup:
-	ldr	r0, _TEXT_BASE		@ upper 128 KiB: relocated uboot
-	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area
-	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo
-#ifdef CONFIG_USE_IRQ
-	sub	r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ)
-#endif
-	sub	sp, r0, #12		@ leave 3 words for abort-stack
-	bic	sp, sp, #7		@ 8-byte alignment for ABI compliance
-
-	/* Clear BSS (if any). Is below tx (watch load addr - need space) */
-clear_bss:
-	ldr	r0, _bss_start		@ find start of bss segment
-	ldr	r1, _bss_end		@ stop here
-	mov	r2, #0x00000000		@ clear value
-clbss_l:
-	str	r2, [r0]		@ clear BSS location
-	cmp	r0, r1			@ are we at the end yet
-	add	r0, r0, #4		@ increment clear index pointer
-	bne	clbss_l			@ keep clearing till at end
-
-	ldr	pc, _start_armboot	@ jump to C code
+_board_init_r_ofs:
+	.word board_init_r - _start
 
-_start_armboot: .word start_armboot
-#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
+_rel_dyn_start_ofs:
+	.word __rel_dyn_start - _start
+_rel_dyn_end_ofs:
+	.word __rel_dyn_end - _start
+_dynsym_start_ofs:
+	.word __dynsym_start - _start
 
 /*************************************************************************
  *
@@ -480,7 +406,6 @@ cpu_init_crit:
 
 	.macro get_bad_stack
 #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
-	ldr	r13, _armboot_start		@ setup our mode stack (enter
 	sub	r13, r13, #(CONFIG_SYS_MALLOC_LEN)	@ move past malloc pool
 	sub	r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8) @ move to reserved a couple
 #else
@@ -508,7 +433,7 @@ cpu_init_crit:
 						@ scratch reg.
 	str	r0, [r13]			@ save R0's value.
 #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
-	ldr	r0, _armboot_start		@ get data regions start
+	adr	r0, _start			@ get data regions start
 	sub	r0, r0, #(CONFIG_SYS_MALLOC_LEN)	@ move past malloc pool
 	sub	r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8)	@ move past gbl and a couple
 #else
diff --git a/arch/arm/cpu/armv7/u-boot.lds b/arch/arm/cpu/armv7/u-boot.lds
index d4fd3fc..43abaf9 100644
--- a/arch/arm/cpu/armv7/u-boot.lds
+++ b/arch/arm/cpu/armv7/u-boot.lds
@@ -54,6 +54,14 @@ SECTIONS
 		*(.data.rel.ro)
 	}
 
+	. = ALIGN(4);
+	__rel_dyn_start = .;
+	.rel.dyn : { *(.rel.dyn) }
+	__rel_dyn_end = .;
+
+	__dynsym_start = .;
+	.dynsym : { *(.dynsym) }
+
 	__got_start = .;
 	. = ALIGN(4);
 	.got : { *(.got) }
diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h
index 2463be4..cf73f27 100644
--- a/include/configs/omap3_beagle.h
+++ b/include/configs/omap3_beagle.h
@@ -341,7 +341,7 @@ extern unsigned int boot_flash_type;
 #endif
 
 /* additions for new relocation code, must added to all boards */
-#undef CONFIG_SYS_ARM_WITHOUT_RELOC /* This board is tested with relocation support */
+#define CONFIG_RELOC_FIXUP_WORKS
 #define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
 #define CONFIG_SYS_INIT_SP_ADDR		(LOW_LEVEL_SRAM_STACK - CONFIG_SYS_GBL_DATA_SIZE)



The board hangs shortly after startup:

	U-Boot 2010.09-00100-g2906eb5-dirty (Oct 05 2010 - 09:49:37)

	OMAP3530-GP ES3.0, CPU-OPP2, L3-165MHz, Max CPU Clock 600 mHz
	OMAP3 Beagle board + LPDDR/NAND
	I2C: 



More information about the U-Boot mailing list