uboot 下 cmd 出问题

问题,我想知道为什么链接器在链接的时候没有把链接脚本中符号的地址填充到代码中相应位置?
http://blog.chinaunix.net/uid-122754-id-3144920.html
环境
系统:ubuntu-12.04  
编译器:arm-none-eabi-gcc (Sourcery CodeBench Lite 2011.09-69) 4.6.1
u-boot版本:2012.10

u-boot的command.c中有个函数使用了链接脚本中的符号__u_boot_cmd_end和__u_boot_cmd_start
C/C++ code
?
1
2
3
4
5
cmd_tbl_t *find_cmd ( const  char  *cmd)
{
     int  len = &__u_boot_cmd_end - &__u_boot_cmd_start;
     return  find_cmd_tbl(cmd, &__u_boot_cmd_start, len);
}


从反汇编可以看出&__u_boot_cmd_start和&__u_boot_cmd_end的值分别被编译器存放在c5e07700和c5e076fc
c5e076d8:       e59f1020        ldr     r1, [pc, #32]   ; c5e07700 <find_cmd+0x40>
c5e076dc:       e59f2018        ldr     r2, [pc, #24]   ; c5e076fc <find_cmd+0x3c>

查看那两个单元,反汇编代码中给出的是...:
c5e076f8:       eaffffc9        b       c5e07624 <find_cmd_tbl>
        ...
c5e07704:       c5e2719c        strbgt  r7, [r2, #412]! ; 0x19c

不死心,将代码下载到板上内存c5e00000处,然后显示内存,可以看到这两个单元的值都为0:
SMDK6410 # md c5e076f8
c5e076f8: eaffffc9 00000000 00000000 c5e2719c    .............q..

System.map中可以看到这两个符号的地址
c5e2af74 A __u_boot_cmd_start
c5e2b4b4 A __u_boot_cmd_end

因为在c代码中得不到这两个符号的值,所以在u-boot中执行任何命令都只能得到提示:
Unknown command 'md' - try 'help'

下面给出链接参数,及链接脚本文件。
链接参数:
C/C++ code
?
1
arm-none-eabi-ld  -pie -T /design/source/smdk6410/u-boot.lds -Bstatic -Ttext 0xc5e00000 $UNDEF_SYM arch/arm/cpu/arm1176/start.o ...... /design/source/smdk6410/arch/arm/lib/eabi_compat.o  -L /design/tools/arm-2011.09/bin/../lib/gcc/arm-none-eabi/4.6.1 -lgcc -Map u-boot.map -o u-boot


链接脚本:
C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
OUTPUT_FORMAT( "elf32-littlearm" "elf32-littlearm" "elf32-littlearm" )
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
  . = 0x00000000;
  . = ALIGN(4);
  .text :
  {
    *(.text)
  }
  . = ALIGN(4);
  .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
  . = ALIGN(4);
  .data : { *(.data) }
  . = ALIGN(4);
  .got : { *(.got) }
  __u_boot_cmd_start = .;
  .u_boot_cmd : { *(.u_boot_cmd) }
  __u_boot_cmd_end = .;
  . = ALIGN(4);
  .mmudata : { *(.mmudata) }
  . = ALIGN(4);
  .rel.dyn : {
   __rel_dyn_start = .;
   *(.rel*)
   __rel_dyn_end = .;
  }
  .dynsym : {
   __dynsym_start = .;
   *(.dynsym)
  }
  _end = .;
  .bss __rel_dyn_start (OVERLAY) : {
   __bss_start = .;
   *(.bss)
   . = ALIGN(4);
   __bss_end__ = .;
  }
  /DISCARD/ : { *(.dynstr*) }
  /DISCARD/ : { *(.dynamic*) }
  /DISCARD/ : { *(.plt*) }
  /DISCARD/ : { *(.interp*) }
  /DISCARD/ : { *(.gnu*) }
}                       


嗯,找到原因了,终于可以睡觉了!

这个是因为ld使用了-pie选项,而程序在运行时并没有进行动态重定位,所在导致符号地址为空。由此推断,当ld使用了-pie选项后,部分符号的地址是在运行过程中确定的,并需要相关代码的配合进行初始化。

你可能感兴趣的:(uboot 下 cmd 出问题)