[U-Boot] relocation problem on powerpc
Joakim Tjernlund
joakim.tjernlund at transmode.se
Tue Sep 9 11:05:27 CEST 2014
Chris Packham <judge.packham at gmail.com> wrote on 2014/09/09 01:07:51:
> From: Chris Packham <judge.packham at gmail.com>
> To: Joakim Tjernlund <joakim.tjernlund at transmode.se>,
> Cc: u-boot <u-boot at lists.denx.de>
> Date: 2014/09/09 01:08
> Subject: Re: [U-Boot] relocation problem on powerpc
>
> Hi Jocke,
>
> On Tue, Sep 9, 2014 at 12:22 AM, Joakim Tjernlund
> <joakim.tjernlund at transmode.se> wrote:
> >>
> >> >
> >> > 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
> >
>
> Here's some more info from a build without any of my modifications.
>
> $ git describe
> v2014.10-rc2-12-g0b703db
>
> $ powerpc-e500-linux-gnu-gcc --version
> powerpc-e500-linux-gnu-gcc (Gentoo 4.6.3-r1 p1.9, pie-0.5.2) 4.6.3
>
> $ grep '_GOT2_TABLE_\|_GLOBAL_OFFSET_TABLE_\|__got2_entries'
u-boot.map
> 0x00000000effb5100 _GOT2_TABLE_ = .
> 0x00000000effb7d38 _GLOBAL_OFFSET_TABLE_
> 0x00000000effb7d48 PROVIDE (_GLOBAL_OFFSET_TABLE_, (. +
0x4))
> 0x0000000000000b0d __got2_entries =
> (((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 0x2) - 0x1)
>
> $ gdb-multiarch u-boot
> (gdb) disassemble /r 0xeffb5100,0xeffb7d48
> Dump of assembler code from 0xeffb5100 to 0xeffb7d48:
> 0xeffb5100 <_GOT2_TABLE_+0>: ef fb 51 00 .long 0xeffb5100
> 0xeffb5104 <_GOT2_TABLE_+4>: ef fb 7d 44 dtstsf cr7,f27,f15
> 0xeffb5108 <_GOT2_TABLE_+8>: ef f4 00 00 .long 0xeff40000
> 0xeffb510c <_GOT2_TABLE_+12>: ef f4 01 00 .long
0xeff40100
> <snip>
> 0xeffb7d30 <_GOT2_TABLE_+11312>: ef f6 6e 74 .long
0xeff66e74
> 0xeffb7d34 <_GOT2_TABLE_+11316>: f0 00 00 d0 psq_st
f0,208(r0),0,0
> 0xeffb7d38 <_GLOBAL_OFFSET_TABLE_+0>: 00 00 00 00 .long
0x0
> 0xeffb7d3c <_GLOBAL_OFFSET_TABLE_+4>: 00 00 00 00 .long
0x0
> 0xeffb7d40 <_GLOBAL_OFFSET_TABLE_+8>: 00 00 00 00 .long
0x0
> 0xeffb7d44 <_FIXUP_TABLE_+0>: ef fb 99 d4 .long
0xeffb99d4
>
> So no there is no brlr at the end of the table.
There should be, see
http://www.freescale.com/files/32bit/doc/ref_manual/E500ABIUG.pdf, chap
4.3.2
>
> Also I think the __got2_entries calculation does not take into account
> the +0x4, ((0xeffb7d38-0xeffb5100)>>2)-1) = 0xb0d
Yes, there is something fishy here but I don't think it is the -1 that is
the problem. It is the
lack of brlr, I am not sure why this happens.
Jocke
More information about the U-Boot
mailing list