public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] Trying to understand ARM926EJS/start.S
@ 2010-10-30 18:09 Reinhard Meyer
  2010-10-30 18:54 ` Albert ARIBAUD
  0 siblings, 1 reply; 8+ messages in thread
From: Reinhard Meyer @ 2010-10-30 18:09 UTC (permalink / raw)
  To: u-boot

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] Trying to understand ARM926EJS/start.S
  2010-10-30 18:09 [U-Boot] Trying to understand ARM926EJS/start.S Reinhard Meyer
@ 2010-10-30 18:54 ` Albert ARIBAUD
  2010-10-30 19:21   ` Wolfgang Denk
  2010-10-30 19:23   ` Reinhard Meyer
  0 siblings, 2 replies; 8+ messages in thread
From: Albert ARIBAUD @ 2010-10-30 18:54 UTC (permalink / raw)
  To: u-boot

Le 30/10/2010 20:09, Reinhard Meyer a ?crit :

> %%% both yield constants that are in TEXT and can be accessed
> %%% PC relative, right?

Constants, yes; in .text, yes; can be accessed pc-relative, yes, as any 
other location in .text actually. But you probably meant "expected to be 
accessed PC relative", in which case: yes.

> %%% adr reg, label sets reg to the address of label?
> %%% ldr reg, label sets reg to the content of mem at label?

Correct.

> 	ldr	r2, _TEXT_BASE
> $$$ r2 is overwritten two lines below, right?
> 	ldr	r3, _bss_start_ofs
> 	add	r2, r0, r3		/* r2<- source end address	    */

Correct.

> 	ldr	r0, _TEXT_BASE		/* r0<- Text base */
> %%% why are we using _TEXT_BASE here and not _start?

Because we're accessing the relocation tables in the FLASH (or freshly 
NAND-loaded) "source" copy of u-boot, not in the RAM "target" copy (in 
which the relocation tables won't exist).

> 	ldr	r3, _TEXT_BASE		/* Text base */
> $$$ r3 is not used below this

If it is useless then it can be removed (but would not cause any issue). 
Note that it may be used implicitly as the 3rd argument to a C function 
call... But I don't think it is, no function called below uses 3 
arguments I think.

> 	mov	r4, r7			/* reloc addr */
> %%% why move it to r4? could we not add r7 in the next 2 lines?

We could indeed -- actually, we could probably otimize register usage in 
other places too.

> 	bne	clbss_l
> %%% this should better be blo, just in case _end is not aligned?

Correct. I thinought I'd sent a patch to fix all these... Seems I missed 
some.

> %%% I cannot see anything here that would prevent BSS being cleared.

Neither do I -- if you think of Alexander's issue, I think it is not 
related to BSS initialization.

> Best Regards,
> Reinhard

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] Trying to understand ARM926EJS/start.S
  2010-10-30 18:54 ` Albert ARIBAUD
@ 2010-10-30 19:21   ` Wolfgang Denk
  2010-10-30 21:56     ` Albert ARIBAUD
  2010-10-30 19:23   ` Reinhard Meyer
  1 sibling, 1 reply; 8+ messages in thread
From: Wolfgang Denk @ 2010-10-30 19:21 UTC (permalink / raw)
  To: u-boot

Dear Albert ARIBAUD,

In message <4CCC69E4.8090103@free.fr> you wrote:
> 
> > 	ldr	r0, _TEXT_BASE		/* r0<- Text base */
> > %%% why are we using _TEXT_BASE here and not _start?
>
> Because we're accessing the relocation tables in the FLASH (or freshly
> NAND-loaded) "source" copy of u-boot, not in the RAM "target" copy (in
> which the relocation tables won't exist).

Sorry, but I don't understand this explanation.

With the linker script we make sure that the symbol _start gets linked
to the absolute address CONFIG_SYS_TEXT_BASE, right?  And _TEXT_BASE
is a storage that holds exactly the value CONFIG_SYS_TEXT_BASE, which
should be identical to the address of _start ?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
The trouble with our times is that the future is not what it used  to
be.                                                     - Paul Valery

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] Trying to understand ARM926EJS/start.S
  2010-10-30 18:54 ` Albert ARIBAUD
  2010-10-30 19:21   ` Wolfgang Denk
@ 2010-10-30 19:23   ` Reinhard Meyer
  2010-10-30 19:30     ` Reinhard Meyer
  2010-10-30 20:12     ` Wolfgang Denk
  1 sibling, 2 replies; 8+ messages in thread
From: Reinhard Meyer @ 2010-10-30 19:23 UTC (permalink / raw)
  To: u-boot

On 30.10.2010 20:54, Albert ARIBAUD wrote:
> Le 30/10/2010 20:09, Reinhard Meyer a ?crit :
>
>> %%% both yield constants that are in TEXT and can be accessed
>> %%% PC relative, right?
>
> Constants, yes; in .text, yes; can be accessed pc-relative, yes, as any other location in .text actually. But you probably meant "expected to be accessed PC relative", in which case: yes.
Yes, I meant the latter.
>
>> %%% adr reg, label sets reg to the address of label?
>> %%% ldr reg, label sets reg to the content of mem at label?
>
> Correct.
>
>> ldr r2, _TEXT_BASE
>> $$$ r2 is overwritten two lines below, right?
So this line is some remnant of earlier code and can be removed
>> ldr r3, _bss_start_ofs
>> add r2, r0, r3 /* r2<- source end address */
>
> Correct.
>
>> ldr r0, _TEXT_BASE /* r0<- Text base */
>> %%% why are we using _TEXT_BASE here and not _start?
>
> Because we're accessing the relocation tables in the FLASH (or freshly NAND-loaded) "source" copy of u-boot, not in the RAM "target" copy (in which the relocation tables won't exist).
Which, by definition, is at TEXT_BASE, so _start should be identical and
adr r0, _start should have the same result?
>
>> ldr r3, _TEXT_BASE /* Text base */
>> $$$ r3 is not used below this
>
> If it is useless then it can be removed (but would not cause any issue). Note that it may be used implicitly as the 3rd argument to a C function call... But I don't think it is, no function called below uses 3 arguments I think.
That would be bad style. Sure it is not used later.
>
>> mov r4, r7 /* reloc addr */
>> %%% why move it to r4? could we not add r7 in the next 2 lines?
>
> We could indeed -- actually, we could probably otimize register usage in other places too.
>
>> bne clbss_l
>> %%% this should better be blo, just in case _end is not aligned?
>
> Correct. I thinought I'd sent a patch to fix all these... Seems I missed some.

I'm still thinking of the idea to move the general, non specific bits of
relocation and bss clearing to a general file; or even better to do most
of it in C. We should just need a small asm helper function to change stack
and branch to the relocated code.

>
>> %%% I cannot see anything here that would prevent BSS being cleared.
>
> Neither do I -- if you think of Alexander's issue, I think it is not related to BSS initialization.

No, since everything works fine here (though I cannot confirm BSS gets cleared,
maybe none of the code active here assumes cleared BSS:) ), but I am sure ALL
code and vars is really accessed at the final, high end RAM location. I filled
all RAM upto 2MB below the end with garbage and nothing crashed and u-boot
still behaved proper.

Alexander's issue cannot be related to a general u-boot problem, it must be
SoC or board specific or handling specific. As to what we can only speculate.

I can only advise again to check for static vars that are used before relocation
(which need not lead to a crash), but their values will be lost during
relocation. This made timers fail here because clock frequencies calculated
in timer init before relocation and stored in static vars were gone after
relocation.

Oh, and u-boot did not work here when compiled with gcc 4.4.5 - I almost forgot
about that... I think I even mentioned that in some message a while ago, but I
can't find it right now.

Best Regards, Reinhard

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] Trying to understand ARM926EJS/start.S
  2010-10-30 19:23   ` Reinhard Meyer
@ 2010-10-30 19:30     ` Reinhard Meyer
  2010-10-30 20:12     ` Wolfgang Denk
  1 sibling, 0 replies; 8+ messages in thread
From: Reinhard Meyer @ 2010-10-30 19:30 UTC (permalink / raw)
  To: u-boot

> Oh, and u-boot did not work here when compiled with gcc 4.4.5 - I almost forgot
> about that... I think I even mentioned that in some message a while ago, but I
> can't find it right now.

Aah, it was 4.3.5:

Re: [U-Boot]  Followup: GCC-4.3.5 and U-Boot (arm, reloc) not working>
at 11.10.2010

Best Regards,
Reinhard

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] Trying to understand ARM926EJS/start.S
  2010-10-30 19:23   ` Reinhard Meyer
  2010-10-30 19:30     ` Reinhard Meyer
@ 2010-10-30 20:12     ` Wolfgang Denk
  1 sibling, 0 replies; 8+ messages in thread
From: Wolfgang Denk @ 2010-10-30 20:12 UTC (permalink / raw)
  To: u-boot

Dear Reinhard Meyer,

In message <4CCC709F.20306@emk-elektronik.de> you wrote:
>
> > Neither do I -- if you think of Alexander's issue, I think it is not related to BSS initialization.
>
> No, since everything works fine here (though I cannot confirm BSS gets cleared,
> maybe none of the code active here assumes cleared BSS:) ), but I am sure ALL
> code and vars is really accessed at the final, high end RAM location. I filled
> all RAM upto 2MB below the end with garbage and nothing crashed and u-boot
> still behaved proper.

Well, if you like then just make an experiment and replace the

	mov     r2, #0x00000000         /* clear */

by something like

	mov     r2, #0xA5A5A5A5         /* clear */

and watch your system go kaboom...


> Alexander's issue cannot be related to a general u-boot problem, it must be
> SoC or board specific or handling specific. As to what we can only speculate.
>
> I can only advise again to check for static vars that are used before relocation
> (which need not lead to a crash), but their values will be lost during
> relocation. This made timers fail here because clock frequencies calculated
> in timer init before relocation and stored in static vars were gone after
> relocation.

That would most likely be driver stuff, which is shared with other
boards, so thse should show similar issues.

My bet is on errors in the initial RAM setup - like unaligned intial
stack (which would also explain the bogus RAM sizes printed, with the
hex numbers not even corresponding to the decimal decoding), and/or
tool chain issues (I've seen way too many optimizer bugs in GCC >= 4.3
lately).

> Oh, and u-boot did not work here when compiled with gcc 4.4.5 - I almost forgot
> about that... I think I even mentioned that in some message a while ago, but I
> can't find it right now.

I'm neither surprised nor amused.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
I have often regretted my speech, never my silence.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] Trying to understand ARM926EJS/start.S
  2010-10-30 19:21   ` Wolfgang Denk
@ 2010-10-30 21:56     ` Albert ARIBAUD
  2010-10-30 22:02       ` Albert ARIBAUD
  0 siblings, 1 reply; 8+ messages in thread
From: Albert ARIBAUD @ 2010-10-30 21:56 UTC (permalink / raw)
  To: u-boot

Le 30/10/2010 21:21, Wolfgang Denk a ?crit :
> Dear Albert ARIBAUD,
>
> In message<4CCC69E4.8090103@free.fr>  you wrote:
>>
>>> 	ldr	r0, _TEXT_BASE		/* r0<- Text base */
>>> %%% why are we using _TEXT_BASE here and not _start?
>>
>> Because we're accessing the relocation tables in the FLASH (or freshly
>> NAND-loaded) "source" copy of u-boot, not in the RAM "target" copy (in
>> which the relocation tables won't exist).
>
> Sorry, but I don't understand this explanation.
>
> With the linker script we make sure that the symbol _start gets linked
> to the absolute address CONFIG_SYS_TEXT_BASE, right?  And _TEXT_BASE
> is a storage that holds exactly the value CONFIG_SYS_TEXT_BASE, which
> should be identical to the address of _start ?

Somehow I thought the question was "why use the source location rather 
than the target".

Yes, if we're still running from the "source" address at that point, the 
value of _start and the content of _TEXT_BASE should be the same -- that 
does change once we start the fixup loop, though; after the loop is 
done, I think "adr r0, _start" will still give us the source start 
address but _TEXT_BASE will contain the target start address -- though 
at this time of the evening I'd want to be careful about that.

Tomorrow morning I'll run a step-by-step case on my ED Mini V2 and on my 
OpenRD and see if / where we can use "adr rX, _start".

> Best regards,
>
> Wolfgang Denk

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] Trying to understand ARM926EJS/start.S
  2010-10-30 21:56     ` Albert ARIBAUD
@ 2010-10-30 22:02       ` Albert ARIBAUD
  0 siblings, 0 replies; 8+ messages in thread
From: Albert ARIBAUD @ 2010-10-30 22:02 UTC (permalink / raw)
  To: u-boot

Le 30/10/2010 23:56, Albert ARIBAUD a ?crit :

> after the loop is
> done, I think "adr r0, _start" will still give us the source start
> address but _TEXT_BASE will contain the target start address -- though
> at this time of the evening I'd want to be careful about that.

Scratch that. After the loop, the _TEXT_BASE of the target location will 
contain the target _start, but the _TEXt_BASE of relocate_code() will 
keep on containing the source _start. Really time I went to sleep.

Apologies,
-- 
Albert.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-10-30 22:02 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-30 18:09 [U-Boot] Trying to understand ARM926EJS/start.S Reinhard Meyer
2010-10-30 18:54 ` Albert ARIBAUD
2010-10-30 19:21   ` Wolfgang Denk
2010-10-30 21:56     ` Albert ARIBAUD
2010-10-30 22:02       ` Albert ARIBAUD
2010-10-30 19:23   ` Reinhard Meyer
2010-10-30 19:30     ` Reinhard Meyer
2010-10-30 20:12     ` Wolfgang Denk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox