[U-Boot] Problem with ll_entry_* before relocation

Heiko Schocher hs at denx.de
Fri Feb 1 10:53:50 CET 2013


Hello,

I am currently trying to get rid of some externs in the new i2c
multibus approach, specially this externs:

http://git.denx.de/?p=u-boot/u-boot-i2c.git;a=blob;f=drivers/i2c/i2c_core.c;h=2a559c9d81a945f219eab49d11e70c0ac4a6d6a4;hb=83ffd31c590dd5aedfef0c195b1ffc406e6d0e37#l31

I tried to use the ll_entry_* defines see:
include/linker_lists.h
so the compiler will collect all i2c adapter(s), and no
need to declare in the config file a list of used adapters.
This approach works fine for using i2c after relocation, but
did not work before, which is a must have for i2c ...
Therefore I describe (Sorry, for the long EMail) here, whats
I see on an arm926ejs based board, using eldk 5.2 with

[hs at pollux u-boot]$ arm-linux-gnueabi-gcc --version
arm-linux-gnueabi-gcc (GCC) 4.6.4 20120303 (prerelease)

and hope someone has an idea or at least an explanation,
why it is not working ...

First the defines I used for include/i2c.h (here shortened
the defines just using one unsigned long var, not the
"struct i2c_adap"):

#define U_BOOT_I2C_MKENT_COMPLETE_TRY(_hwadapnr) \
        _hwadapnr;

#define U_BOOT_I2C_ADAP_COMPLETE_TRY(_name, _hwadapnr) \
        ll_entry_declare(unsigned long, _name, try, try) = \
        U_BOOT_I2C_MKENT_COMPLETE_TRY( _hwadapnr);

which i can use in drivers/i2c/soft_i2c.c as

U_BOOT_I2C_ADAP_COMPLETE_TRY(soft0, 0)
U_BOOT_I2C_ADAP_COMPLETE_TRY(soft1, 1)

Following printf in for example i2c_set_bus_num():

int i2c_set_bus_num(unsigned int bus)
{
        extern unsigned long _u_boot_list_try__start;

printf("%08lx  %08lx\n", (unsigned long)_u_boot_list_try__start,
(unsigned long)&_u_boot_list_try__start);

results in an output:
before relocation
e59ff00c  00000000
          ^
          wrong address (Explanation see below)
after relocation:
00000000  a7fb5d08
          ^
          correct address

so, "&_u_boot_list_try__start" is only valid after relocation!

Debugging deeper in it ...
Objdump:

000000a4 <i2c_set_bus_num>:
        extern unsigned long _u_boot_list_try__start;

printf("%08lx  %08lx\n", (unsigned long)_u_boot_list_try__start,
(unsigned long)&_u_boot_list_try__start);
  a4:   e59f2014        ldr     r2, [pc, #20]   ; c0 <i2c_set_bus_num+0x1c>
 *      bus - bus index, zero based
 *
 *      Returns: 0 on success, not 0 on failure
 */
int i2c_set_bus_num(unsigned int bus)
{
  a8:   e92d4008        push    {r3, lr}
        extern unsigned long _u_boot_list_try__start;

printf("%08lx  %08lx\n", (unsigned long)_u_boot_list_try__start,
(unsigned long)&_u_boot_list_try__start);
  ac:   e5921000        ldr     r1, [r2]
  b0:   e59f000c        ldr     r0, [pc, #12]   ; c4 <i2c_set_bus_num+0x20>
  b4:   ebfffffe        bl      0 <printf>
        i2c_mux_set_all();

breakpoint in i2c_set_bus_num

System.map:
c001221c T i2c_set_bus_num

Core#0>bi 0xc001221c
Breakpoint identification is 0
Core#0>g
- TARGET: core #0 has entered debug mode
Core#0>i
    Core number       : 0
    Core state        : debug mode (ARM)
    Debug entry cause : Breakpoint
    Current PC        : 0xc001221c
    Current CPSR      : 0x600000d3 (Supervisor)
Core#0>r
GPR00: 00000000 c0030aeb 00000060 c001f028
GPR04: c0038ea4 fffffffc a7fb46c4 c0000b70
GPR08: a0000f00 00000001 c0000164 00000001
GPR12: 00000000 a0000ee0 c0000b80 c001221c
PC   : c001221c    CPSR: 600000d3
Core#0>md 0xc001221c
c001221c : e59f2014 e92d4008 e5921000 e59f000c  . ... at -.........
c001222c : ebffe57c e3a00000 e8bd8008 00000000  |...............
                                      ^
                                      wrong should be
                                      c003bd08
c001223c : c003674c e92d4008 ebffc80c e3a00000  Lg... at -.........
c001224c : e8bd4008 eafffff1 e92d40f8 e598307c  . at .......@-.|0..
[...]
Core#0>r
GPR00: 00000000 c0030aeb 00000060 c001f028
GPR04: c0038ea4 fffffffc a7fb46c4 c0000b70
GPR08: a0000f00 00000001 c0000164 00000001
GPR12: 00000000 a0000ee0 c0000b80 c001221c
PC   : c001221c    CPSR: 600000d3

from objdump pc @ 0xc001221c:
  a4:	e59f2014 	ldr	r2, [pc, #20]	; c0 <i2c_set_bus_num+0x1c>

load r2   with c001221c + 1c (0xc0012238) = 0 ....

thats wrong, as _u_boot_list_try__start is c003bd08 ...

System.map:
c003bd08 D _u_boot_list_i2c__end
c003bd08 D _u_boot_list_try__start
c003bd08 D _u_boot_list_try_soft0
c003bd0c D _u_boot_list_try_soft1
c003bd10 A __image_copy_end
[...]

After relocation:

relo addr from i2c_set_bus_num:

c001221c + 0xE7F7A000 = a7f8c21c

Core#0>bi 0xa7f8c21c
Breakpoint identification is 0
Core#0>g
- TARGET: core #0 has entered debug mode
Core#0>i
    Core number       : 0
    Core state        : debug mode (ARM)
    Debug entry cause : Breakpoint
    Current PC        : 0xa7f8c21c
    Current CPSR      : 0x600000d3 (Supervisor)
Core#0>r
GPR00: 00000000 a7ec8e50 00000060 00000083
GPR04: 00000000 a7fb5940 00000000 a7ec9ec8
GPR08: a7ec9f60 00000000 00000003 a7ec92d1
GPR12: 00000034 a7ec9280 a7f7dcf8 a7f8c21c
PC   : a7f8c21c    CPSR: 600000d3
Core#0>

Core#0>md 0xa7f8c21c
a7f8c21c : e59f2014 e92d4008 e5921000 e59f000c  . ... at -.........
a7f8c22c : ebffe57c e3a00000 e8bd8008 a7fb5d08  |............]..
                                      ^
a7f8c23c : a7fb074c e92d4008 ebffc80c e3a00000  L.... at -.........
a7f8c24c : e8bd4008 eafffff1 e92d40f8 e598307c  . at .......@-.|0..
a7f8c25c : e3a0601c e0030396 e59f5028 e1a07000  .`......(P...p..
[...]
Core#0>

  a4:	e59f2014 	ldr	r2, [pc, #20]	; c0 <i2c_set_bus_num+0x1c>

load r2 with pc:0xa7f8c21c + 1c = 0xa7f8c238 = a7fb5d08 ....
thats the correct value ... because:

c003bd08 + 0xE7F7A000 = 1a7fb5d08 relocated addr from
_u_boot_list_try__start

with:
c003bd08 D _u_boot_list_try__start
c003bd08 D _u_boot_list_try_soft0
c003bd0c D _u_boot_list_try_soft1
c003bd10 A __image_copy_end

So, the question is, why is in the u-boot image the
wrong value 0 for _u_boot_list_try__start?

Additionally, if I print "_u_boot_list_try_soft0" with

printf("%08lx  %08lx\n", (unsigned long)_u_boot_list_try_soft0,
(unsigned long)&_u_boot_list_try_soft0);

It has the correct value before and after relocation ... !!

objdump:
printf("%08lx  %08lx\n", (unsigned long)_u_boot_list_try__start,
(unsigned long)&_u_boot_list_try__start);
  a8:   e59f2024        ldr     r2, [pc, #36]   ; d4 <i2c_set_bus_num+0x30>
  ac:   e59f4024        ldr     r4, [pc, #36]   ; d8 <i2c_set_bus_num+0x34>
  b0:   e5921000        ldr     r1, [r2]
  b4:   e1a00004        mov     r0, r4
  b8:   ebfffffe        bl      0 <printf>
printf("%08lx  %08lx\n", (unsigned long)_u_boot_list_try_soft0,
(unsigned long)&_u_boot_list_try_soft0);
  bc:   e59f2018        ldr     r2, [pc, #24]   ; dc <i2c_set_bus_num+0x38>
  c0:   e1a00004        mov     r0, r4
  c4:   e5921000        ldr     r1, [r2]
  c8:   ebfffffe        bl      0 <printf>
        i2c_mux_set_all();

_u_boot_list_try_soft0 in line bc:
load to r2 from c001221c + 0x38 = 0xc0012254

and c0012254 contain c003bd20, which is the correct value
for _u_boot_list_try_soft0 !!

System.map for this case:
c003bd20 D _u_boot_list_try__start
c003bd20 D _u_boot_list_try_soft0
c003bd24 D _u_boot_list_try_soft1
c003bd28 A __image_copy_end

Core#0>r
GPR00: 00000000 c0030b03 00000060 c001f040
GPR04: c0038ebc fffffffc a7fb46dc c0000b70
GPR08: a0000f00 00000001 c0000164 00000001
GPR12: 00000000 a0000ee0 c0000b80 c001221c
PC   : c001221c    CPSR: 600000d3
Core#0>md 0xc001221c
c001221c : e92d4010 e59f2024 e59f4024 e5921000  . at -.$ ..$@......
c001222c : e1a00004 ebffe57b e59f2018 e1a00004  ....{.... ......
c001223c : e5921000 ebffe577 e3a00000 e8bd8010  ....w...........
c001224c : 00000000 c0036764 c003bd20 e92d4008  ....dg.. .... at -.
           ^                 ^
           ^                 correct value for _u_boot_list_try_soft0
           again, wrong value for _u_boot_list_try__start

So the question is, whats the difference between _u_boot_list_try_soft0
and _u_boot_list_try__start ... any ideas?

Thanks in advance.

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany


More information about the U-Boot mailing list