* [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 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
* [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
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