韦东山Linux嵌入式课程社区
直播中

殷谷光

7年用户 1074经验值
擅长:控制/MCU
私信 关注

为什么重定位的时候BSS段不拷贝过去?

学习毕业班,有几个疑惑的问题,想请教大家,希望解答啊。


(1)为什么重定位的时候BSS段不拷贝过去?如果在SDRAM中调用这些BSS段定义的变量或者地址,不是需要在SDRAM进行地址的转换吗?就跟新的u-boot的做法一样,需要地址转换啊。
     比如,在bss段中有个变量的地址是0x100, 那如果在SDRAM中引用这个变量不是需要地址转换吗?这样不是必须得拷贝这个变量过去吗??

(2)既然bss段没有拷贝过去,为什么存储在SDRAM上u-boot代码总的大小是:__bss_end__ - _start 呢?
        代码重定向拷贝代码不是只拷贝了除BSS段以外代码段和数据段的大小么?   ldr r2, =_bss_start_ofs    // _bss_start_ofs = __bss_start - _start,表示u-boot代码的大小。

(3)还有一个问题是,为什么修改_TEXT_BASE = 0x33f00000以后,反汇编就是从0x33f00000开始呢?
但是在u-boot.lds中的链接地址不是从0 开始的么?
SECtiONS
{
. = 0x00000000;  // 不是从0地址处开始堆放的么???
. = ALIGN(4);
.text :
{
  __image_copy_start = .;
  arch/ARM/cpu/arm920t/start.o (.text)
  board/samsung/smdk2440/libsmdk2440.o (.text)
  *(.text)
}
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
.data : {
  *(.data)
}
. = ALIGN(4);
. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
. = ALIGN(4);
__image_copy_end = .;
.rel.dyn : {
  __rel_dyn_start = .;
  *(.rel*)
  __rel_dyn_end = .;
}
.dynsym : {
  __dynsym_start = .;
  *(.dynsym)
}
_end = .;
. = ALIGN(4096);
.mmutable : {
  *(.mmutable)
}
.bss __rel_dyn_start (OVERLAY) : {
  __bss_start = .;
  *(.bss)
   . = ALIGN(4);
  __bss_end__ = .;
}
/DISCARD/ : { *(.dynstr*) }
/DISCARD/ : { *(.dynamic*) }
/DISCARD/ : { *(.plt*) }
/DISCARD/ : { *(.interp*) }
/DISCARD/ : { *(.gnu*) }
}

回帖(2)

刘溪

2019-7-30 11:00:18
你好,第三个问题我也搞不懂,朋友你现在搞懂了吗?
举报

李燕

2019-7-30 11:06:46
1.BSS段存放的到值为0,或未初始化的变量。既然它们的值是0,我干嘛要拷贝0过去?
     我直接把放些变量所在的内存清零就可以了。

     BSS段有个变量地址为0x100,我直接把0x100这个地址的值设为0就可以了,不用把0拷过去。

2._bss_start_ofs = __bss_start - _start,表示u-boot代码的大小;不是__bss_end__ - _start

3.你可以看UBOOT编译时的最后一条链接指令,它是:
    arm-linux-ld -T 0x33f80000 -Tu-boot.lds .....
   所以,链接地址是 0x33f80000 + 0
举报

更多回帖

发帖
×
20
完善资料,
赚取积分