lds文件

语法规则:

section [address] [(type)] :
[AT(lma)]
[ALIGN(section_align) | ALIGN_WITH_INPUT]
[SUBALIGN(subsection_align)]
[constraint]
{
output-section-command
output-section-command
...
} [>region] [AT>lma_region] [:phdr :phdr ...] [=fillexp] [,]


1. output  section 中的 “.”为location counter,   不可以move backward

SECTIONS{

}

2.  output section的assignment语法,要注意link会插入lds中未定义的section,插入的位置默认赋值语句是跟随前一个output sections
例如:
SECTIONS
{
start_of_text = . ;
.text: { *(.text) }
end_of_text = . ;

start_of_data = . ;
.data: { *(.data) }
end_of_data = . ;
}
默认插入.rodata如下:
SECTIONS
{
start_of_text = . ;
.text: { *(.text) }
end_of_text = . ;

start_of_data = . ;
.rodata: { *(.rodata) }
.data: { *(.data) }
end_of_data = . ;
}

导致start_of_data 的值并不是.data sectios的起始值,为解决这个问题,必须插入.赋值语句,link会认为是给后面的output sections设置一个新的起始地址。
如下:
SECTIONS
{
start_of_text = . ;
.text: { *(.text) }
end_of_text = . ;

. = . ;
start_of_data = . ;
.data: { *(.data) }
end_of_data = . ;

}

3. 为防止出以为,output sections尽量写成这样:
.text . : { *(.text) }  
而不要写成
.text : { *(.text) }
第一种text放到当前的location counter
第二种text放到alignment最严格的地方region。所以不一定是放在当前位置。

4. AT潜规则,  如果AT和AT>都没有使用,则按照下面顺序的规则
1. 如果有指定具体的VMA地址,如 .text 0x1000 : { *(.text) _etext = . ; }, 则LMA=VMA;
2. 如果section是not allocatable的,则LMA=VMA;  比如type为OVERLAY的时候是not allocatable
3. 如果能找到能兼容当前section的memory region,且已经至少有一个section,那么LMA设置为与已经定位到该region最后一个section相同的差值(LMA和VMA)
4. 如果没有定义memory region,那么默认为region是包含所有完整的地址空间,且同样应用上面第3点
5. 如果有定义memory region,但是找不到合适属性的region,或者能找到合适的region,但是没有之前没有section定位到该region,则LMA=VMA;

5. output section address潜规则:
1. 有指定输出地址的放在指定输出地址,按照output section内部最严alignment对齐。
2. 没有指定地址的,如果有指定region,就放在该region下的free位置。
3. 如果都没有指定,从MEMROY列表中找第一个满足属性要求的memory region,放在该region的free位置
4. 如果也没有memory列表,则放在当前的location counter位置,也就是“.”的位置。

6. lds文件编写规则有2种习惯,
第1种不定义memory region,必须使用ld默认的段,比如:.text,.bss,  .data, .rodata等,不使用自定义的段,不适用绝对定位
第2种定义memory region, 可以自定义section放到相应的region。可以实现绝对定位。

7. 绝对定位的方法:
代码中:
unsigned char __attribute__((section (".myBufSection"))) buf[128];
lds中:
MEMORY
{
  m_interrupts  (rx) : ORIGIN = 0x00000000, LENGTH = 0xC0
  m_cfmprotrom  (rx) : ORIGIN = 0x00000400, LENGTH = 0x10
  m_text        (rx) : ORIGIN = 0x00000800, LENGTH = 128K - 0x800
  m_data       (rwx) : ORIGIN = 0x1FFFF000, LENGTH = 16K
}
SECTIONS
{
  /* placing my named section at given address: */
  .myBufBlock 0x20000000 :
  {
    KEEP(*(.myBufSection)) /* keep my variable even if not referenced */
  } > m_data
 
  /* other placements follow here... */
}

8. 如果不使用memory语法定义region,当使用AT定位使得 则LMA != VMA; 那么同一个region的后面的section会默认顺延这种AT关系,为防止这种情况导致错误,必须在下一个section显示定义AT,使得LMA = VMA,例如N2 bos的代码lds脚本:
.dummy :
  {
    . = . + 0x10000;
  }
  .data : AT( ADDR (.dummy) )
  {
    __data_at_start = LOADADDR(.data);
    __data_start = . ;
    *(.data .data.* .gnu.linkonce.d.*)
    SORT(CONSTRUCTORS)
  }
  .data1 : { *(.data1) }
  _edata = .; PROVIDE (edata = .);
  . = .;
  . = ALIGN(16);
  __bss_start = .;
  __bss_start__ = .;
  .bss : AT( ADDR (.bss) )
  {
   *(.dynbss)
   *(.bss .bss.* .gnu.linkonce.b.*)
   *(COMMON)
   . = ALIGN(. != 0 ? 16 : 1);
  }


9. 哪些东西会放到bin中?  正常来说.text , .rodata; .data 这些段会放到bin中做code。可以加-R 去掉不要的段。去掉中间的段不能减少bin文件大小,如下:
$(OBJCOPY) -O binary -R .note.gnu.build-id -R .share_data $(APP).elf $(APP).bin

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值