[U-Boot] relocation problem on powerpc

Joakim Tjernlund joakim.tjernlund at transmode.se
Mon Sep 8 14:22:10 CEST 2014


> 
> > 
> > There are some disadvantages to living in a weird timezone, mostly
> > that you end up having conversations with yourself.
> > 
> > On Mon, Sep 8, 2014 at 4:32 PM, Chris Packham 
<judge.packham at gmail.com> 
> wrote:
> > > Hi All,
> > >
> > > I have come across what I think is a relocation problem for powerpc.
> > >
> > > I've added the following to ArpTimeoutCheck
> > >
> > > +       printf("NetArpWaitTimerStart = %ld\n", 
NetArpWaitTimerStart);
> > > +       printf("&NetArpWaitTimerStart = %p\n", 
&NetArpWaitTimerStart);
> > > +       printf("NetArpWaitTry = %d\n", NetArpWaitTry);
> > > +       printf("&NetArpWaitTry = %p\n", &NetArpWaitTry);
> > > +       printf("NetArpWaitTxPacketSize = %d\n", 
> NetArpWaitTxPacketSize);
> > > +       printf("&NetArpWaitTxPacketSize = %p\n", 
> &NetArpWaitTxPacketSize);
> > >
> > > Which yields the following output
> > >
> > >   NetArpWaitTimerStart = 0
> > >   &NetArpWaitTimerStart = f00000d0
> > >   NetArpWaitTry = 1
> > >   &NetArpWaitTry = 7ffb0058
> > >   NetArpWaitTxPacketSize = 42
> > >   &NetArpWaitTxPacketSize = 7ffb0078
> > >
> > > That looks to me like NetArpWaitTimerStart hasn't been relocated for
> > > some reason. Looking at my u-boot.map NetArpWaitTimerStart is the 
last
> > > item in the .sbss section
> > >
> > > Here's the relevant snippets for the variables I'm displaying
> > >
> > >  0x00000000f0000058                NetArpWaitTry
> > >  0x00000000f0000078                NetArpWaitTxPacketSize
> > >  0x00000000f00000d0                NetArpWaitTimerStart
> > >
> > > The actual problem for me is that ARPs timeout and various network
> > > things fail. Has anyone got any clues as to why this one particular
> > > variable isn't getting relocated.
> > >
> > > Thanks,
> > > Chris
> > >
> > > More info:
> > >   I'm building P2041RDB_config
> > >
> > >   $ git describe
> > >   v2014.10-rc2-15-g2ec8915
> > >
> > >   => version
> > >   U-Boot 2014.10-rc2-00015-g2ec8915-dirty (Sep 08 2014 - 16:18:42)
> > >   powerpc-e500-linux-gnu-gcc (Gentoo 4.6.3-r1 p1.9, pie-0.5.2) 4.6.3
> > >   GNU ld (GNU Binutils) 2.21
> > 
> > I'm not confident enough to say it's a fix but the following seems to
> > solve the relocation problem for NetArpWaitTimerStart.
> > 
> > diff --git a/arch/powerpc/cpu/mpc85xx/u-boot.lds
> > b/arch/powerpc/cpu/mpc85xx/u-boot.lds
> > index 2cf0b25..36711b0 100644
> > --- a/arch/powerpc/cpu/mpc85xx/u-boot.lds
> > +++ b/arch/powerpc/cpu/mpc85xx/u-boot.lds
> > @@ -54,7 +54,7 @@ SECTIONS
> >      _FIXUP_TABLE_ = .;
> >      KEEP(*(.fixup))
> >    }
> > -  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
> > +  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2);
> >    __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
> 
> This looks like the correct fix, The relevant code that uses 
> __got2_entries is in start.S:
> 
> in_ram:
> 
>         /*
>          * Relocation Function, r12 point to got2+0x8000
>          *
>          * Adjust got2 pointers, no need to check for 0, this code
>          * already puts a few entries in the table.
>          */
>         li      r0,__got2_entries at sectoff@l
>         la      r3,GOT(_GOT2_TABLE_)
>         lwz     r11,GOT(_GOT2_TABLE_)
>         mtctr   r0
>         sub     r11,r3,r11
>         addi    r3,r3,-4
> 1:      lwzu    r0,4(r3)
>         cmpwi   r0,0
>         beq-    2f
>         add     r0,r0,r11
>         stw     r0,0(r3)
> 2:      bdnz    1b
> 
> bdnz does decrement then test for zero so __got2_entries should hold the 

> number of entries to relocate.
> 
> Seems like most(all?) ppc cpu has this error.

Looking at u-boot.lds:
 .reloc   :
  {
    _GOT2_TABLE_ = .;
    KEEP(*(.got2))
    KEEP(*(.got))
    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
    _FIXUP_TABLE_ = .;
    KEEP(*(.fixup))
  }
  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
  __fixup_entries = (. - _FIXUP_TABLE_) >> 2;


There is something more to this error. Since _GLOBAL_OFFSET_TABLE_  is 
defined to
_GLOBAL_OFFSET_TABLE_ = . + 4
there is one extra entry added( for brlr insn inserted by the linker) so 
something is
amiss here, is there a brlr insns at _GLOBAL_OFFSET_TABLE_-4 in your 
u-boot?

 Jocke



More information about the U-Boot mailing list