[U-Boot] [PATCH 2/2] [NEXT] arm926ejs: reduce code size with -msingle-pic-base

Ben Gardiner bengardiner at nanometrics.ca
Thu Sep 23 23:13:05 CEST 2010


On Thu, Sep 23, 2010 at 1:04 PM, Albert ARIBAUD <albert.aribaud at free.fr> wrote:
> Note that if I'm not mistaken, your build uses r9 as the pic base, not 10 --
> this is a possibility, and my patches are written so as to allow either
> register use.

I don't know for sure so I did a little poking around:

c1080688 <board_init_f>:
c1080688:       e59fa118        ldr     sl, [pc, #280]  ; c10807a8
<board_init_f+0x120>
c108068c:       e59f8118        ldr     r8, [pc, #280]  ; c10807ac
<board_init_f+0x124>

(gdb) info registers
[...]
r9             0xc1098564       3238626660
r10            0xc1098564       3238626660
[...]
pc             0xc1080688       0xc1080688 <board_init_f>
[...]
(gdb) ni
514             gd = (gd_t *) (CONFIG_SYS_INIT_SP_ADDR);
(gdb) info registers
[...]
r9             0xc1098564       3238626660
r10            0x17ecc  97996
[...]
pc             0xc108068c       0xc108068c <board_init_f+4>
[...]
(gdb) p /x $sl
$1 = 0x17ecc
(gdb) p /x $r10
$2 = 0x17ecc
(gdb) p /x $r9
$3 = 0xc1098564
(gdb) p *0xc10807a8
$4 = 97996
(gdb) p /x *0xc10807a8
$5 = 0x17ecc

I think that confirms that sl == r10 .

> Now, we need to find out why board_init_f fails to go through the init
> sequence and print out at least the banner and some diagnostics.
>
> Please build with my two patches alone (i.e., put -msingle-pic-base back in
> place, which will remove the recomputation of the pic base in every
> function), and run it until board_init_f() calls its first init function
> through (*init_fnc_ptr)(). This call should be materialized by a 'blx <reg>'
> instruction; please report the value of <reg> at that point as well as the
> addresses of arch_cpu_init, board_early_init_f, and timer_init; <reg> should
> be one of these depending on the board config.

<reg> is r10/sl :

        for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
                if ((*init_fnc_ptr)() != 0) {
c1080690:       e12fff3a        blx     sl
c1080694:       e2844004        add     r4, r4, #4      ; 0x4
c1080698:       e3500000        cmp     r0, #0  ; 0x0
c108069c:       0a000000        beq     c10806a4 <board_init_f+0x58>
                        hang ();
c10806a0:       ebffff76        bl      c1080480 <hang>

Here's the addresses you requested for the very first time it hit that
function call through (*init_fnc_prt)():
(gdb) p /x $pc
$4 = 0xc1080690
(gdb) p /x $sl
$5 = 0xc1091e6c
(gdb) p /x $r10
$6 = 0xc1091e6c

There is no arch_cpu_init or board_early_init_f; timer_init is at
0xc1091e6c. So it is timer_init which is being called above.

The call to timer_init completes successfully; the next function
pointer dereferenced and called is 0xc1087e04 == env_init. That call
completes successfully. The next is 0xc10804f8 == init_baudrate; it
completes successfully. The next call is 0xc108119c == serial_init; it
completes successfully. The next is 0xc1086550 == console_init_f; it
completes successfully. The next is 0xc10804d0 == display_banner;  it
completes successfully. They all did. Execution reaches the call to
relocate_code and enters; the last instruction I am able to
single-step is the 'ldr     r10, _got_base' in the following lines
from your patch:

> +       /*
> +        * Set pic base register to the current GOT position. Since we are
> +        * now running from RAM, we need to offset it from its link-time to
> +        *  its run-time position.
> +        */
> +       ldr     r9, relocate_got_base_r
> +       sub     r9, pc, r9
> +       ldr     r10, _got_base
> +relocate_got_base_r:
> +       add     r10, r9, r10
> +       mov     r9, r10
> +

> Thanks again for your help in testing my patches!

My pleasure. I hope we can get them working on the da850evm.

Best Regards,
Ben Gardiner

---
Nanometrics Inc.
http://www.nanometrics.ca


More information about the U-Boot mailing list