[U-Boot] Trying to understand ARM926EJS/start.S

Reinhard Meyer u-boot at emk-elektronik.de
Sat Oct 30 20:09:17 CEST 2010


Hello,

I am not (yet) good at ARM assembler syntax and instructions, so trying
to understand the start.S code is not very easy for me. However I think
I saw some places there that need clarification. All what I see as
suspiscious I have marked with $$$ and just comments with %%% in the
next line.

...
.globl _bss_start_ofs
_bss_start_ofs:
	.word __bss_start - _start

.globl _bss_end_ofs
_bss_end_ofs:
	.word _end - _start
%%% both yield constants that are in TEXT and can be accessed
%%% PC relative, right?
...
reset:
	/*
	 * set the cpu to SVC32 mode
	 */
	mrs	r0,cpsr
	bic	r0,r0,#0x1f
	orr	r0,r0,#0xd3
	msr	cpsr,r0
%%% just style: the rest uses spaces after the comma.
	/*
	 * we do sys-critical inits only at reboot,
	 * not when booting from ram!
	 */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
	bl	cpu_init_crit
#endif

/* Set stackpointer in internal RAM to call board_init_f */
call_board_init_f:
	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
	ldr	r0,=0x00000000
%%% style
	bl	board_init_f

/*------------------------------------------------------------------------------*/

/*
  * void relocate_code (addr_sp, gd, addr_moni)
  *
  * This "function" does not return, instead it continues in RAM
  * after relocating the monitor code.
  *
  */
	.globl	relocate_code
relocate_code:
	mov	r4, r0	/* save addr_sp */
	mov	r5, r1	/* save addr of gd */
	mov	r6, r2	/* save addr of destination */
	mov	r7, r2	/* save addr of destination */

	/* Set up the stack						    */
stack_setup:
	mov	sp, r4

	adr	r0, _start
%%% adr reg, label sets reg to the address of label?
%%% ldr reg, label sets reg to the content of mem at label?
	ldr	r2, _TEXT_BASE
$$$ r2 is overwritten two lines below, right?
	ldr	r3, _bss_start_ofs
	add	r2, r0, r3		/* r2 <- source end address	    */
	cmp	r0, r6
	beq	clear_bss

copy_loop:
	ldmia	r0!, {r9-r10}		/* copy from source address [r0]    */
	stmia	r6!, {r9-r10}		/* copy to   target address [r1]    */
	cmp	r0, r2			/* until source end address [r2]    */
	blo	copy_loop

#ifndef CONFIG_PRELOADER
	/*
	 * fix .rel.dyn relocations
	 */
	ldr	r0, _TEXT_BASE		/* r0 <- Text base */
%%% why are we using _TEXT_BASE here and not _start?
	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	r0, [r2]		/* r0 <- location to fix up, IN FLASH! */
	add	r0, 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
	blo	fixloop
#endif

clear_bss:
#ifndef CONFIG_PRELOADER
	ldr	r0, _bss_start_ofs
%%% r0 = __bss_start - _start
	ldr	r1, _bss_end_ofs
%%% r1 = _end - _start
	ldr	r3, _TEXT_BASE		/* Text base */
$$$ r3 is not used below this
	mov	r4, r7			/* reloc addr */
%%% why move it to r4? could we not add r7 in the next 2 lines?
	add	r0, r0, r4
%%% ok, this yields r0 = __bss_start - _start + "relocated address"
	add	r1, r1, r4
%%% ok, this yields r1 = _end - _start + "relocated address"
	mov	r2, #0x00000000		/* clear			    */

clbss_l:str	r2, [r0]		/* clear loop...		    */
	add	r0, r0, #4
	cmp	r0, r1
	bne	clbss_l
%%% this should better be blo, just in case _end is not aligned?

%%% I cannot see anything here that would prevent BSS being cleared.
	bl coloured_LED_init
	bl red_LED_on
#endif

/*
  * We are done. Do not return, instead branch to second part of board
  * initialization, now running from RAM.
  */
#ifdef CONFIG_NAND_SPL
	ldr     r0, _nand_boot_ofs
	mov	pc, r0

_nand_boot_ofs:
	.word nand_boot
#else
	ldr	r0, _board_init_r_ofs
	adr	r1, _start
	add	lr, r0, r1
	add	lr, lr, r9
	/* setup parameters for board_init_r */
	mov	r0, r5		/* gd_t */
	mov	r1, r7		/* dest_addr */
	/* jump to it ... */
	mov	pc, lr
...

Best Regards,
Reinhard


More information about the U-Boot mailing list