zoukankan      html  css  js  c++  java
  • 嵌入式Linux-linux连接脚本

    嵌入式Linux-linux连接脚本

    介绍

    每一个链接过程都由链接脚本(linker script, 一般以lds作为文件的后缀名)控制。 链接脚本主要用于规定如何把输入文件内的section放入输出文件内, 并控制输出文件内各部分在程序地址空间内的布局。

    链接器在进行链接时,会根据链接脚本从输入的.o文件中挑选出感兴趣的section,把它们合并生成新的section,这些新产生的section归属于目标文件的某个segment(段),并出现在目标文件中。例如file1.o和file2.o分别有两个.text,它们在链接后生产的目标文件也会有一个.text,而这个.text既是由file1.o和file2.o的.text合并而来的。

    终端中使用链接脚本

    代码示例

    //提供名为:test.dls的连接脚本
    arm-linux-ld -Ttest.dls -o test test1.o test2.o
    
    //不提供连接脚本
    arm-linux-ld -o test test1.o test2.o

    具体介绍

    • 如果你不提供链接脚本,则链接器会使用一个缺省的脚本,这个脚本是被编译进链接器可执行文件的.

    • 可以使用–verbose命令行显示缺省的链接器脚本的内容.

      arm-linux-ld --verbose  //查看arm-linux-ld连接的默认连接脚本
      
      ld --verbose    //ld连接的默认连接脚本
    • 你可以使用-T命令行来提供你自己的链接脚本来替换缺省的链接脚本.

      //提供名为:test.dls的连接脚本
      arm-linux-ld -Ttest.dls -o test test1.o test2.o
    • -T选项可以指定数据段,代码段,bss段起始位置。(使用默认连接脚本的选项)

      -Ttext startaddr
      
      -Tdata startaddr
      
      -Tbss  startaddr
      
      //例子示范
      ld –Ttext 0x00000000 –g led_on.o –o led_on_elf

    语法基本介绍

    SECTIONS命令:

    The SECTIONS command tells the linker how to map input sections into output sections, and how to place the output sections in memory.

    命令格式如下:

     SECTIONS 
     {  
        sections-command 
        sections-command 
        ...... 
     }
    

    地址计数器‘.’

    该符号只能用于SECTIONS命令内部,初始值为‘0’,可以对该符号进行赋值,也可以使用该符号进行计算或赋值给其他符号。它会自动根据SECTIONS命令内部所描述的输出段的大小来计算当前的地址。

    输出段描述

    前面提到在SECTIONS命令中可以作输出段描述

    命令格式如下:

    section [address] [(type)] : [AT(lma)] 
    {  
        output-section-command 
        output-section-command ...  
    } [>region] [AT>lma_region] [:phdr :phdr ...] [=fillexp] 

    secname和contents是必须的,其他的都是可选的。下面挑几个常用的看看:

    1. secname:段名
    2. contents:决定哪些内容放在本段,可以是整个目标文件,也可以是目标文件中的某段(代码段、数据段等)
    3. start:定义本段连接(运行)的地址,如果没有使用AT(ldadr),本段存储的地址也是start。GNU网站上说start可以用任意一种描述地址的符号来描述。(连接(运行)的地址:就是当可执行文件,运行时,段的位置)
    4. AT(ldadr):定义本段存储(加载)的地址。(本段存储的地址:就是编译完之后,相应段存储在ELF运行文件中的存储地址)

    例子+解释

    例子

    /* nand.lds */
    SECTIONS { 
    firtst 0x00000000 : { head.o init.o } 
    second 0x30000000 : AT(4096) { main.o } 
    }

    解释

    1. head.o放在0x00000000地址开始处,init.o放在head.o后面,他们的运行地址也是0x00000000,即连接和存储地址相同(没有AT指定);

    2. main.o放在4096(0x1000,是AT指定的,存储地址)开始处,但是它的运行地址在0x30000000,运行之前需要从0x1000(加载处)复制到0x30000000(运行处),此过程也就用到了读取Nand flash。

    3. 这就是存储地址和连接(运行)地址的不同,称为加载时域和运行时域,可以在.lds连接脚本文件中分别指定

    例子+解释

    OUTPUT_ARCH(arm)    //设置编译出来可执行文件的架构 
    ENTRY(_start)           //设置可执行文件起始的的段位置。这里设置了_start,因此在在输入段中,一定存在一个名为_start的段。
    
    SECTIONS {
        . = 0xa3f00000;     //设置起始位置
        __boot_start = .;  //复制参数,在最后用到了
        .start ALIGN(4) :{
                  *(.text.start)     
        }                   //ALIGN(4)表示4字节对齐
    
        .setup ALIGN(4) : {         
                setup_block = .;         
                *(.setup)          
                setup_block_end = .;     
        }
    
        .text ALIGN(4) : {         
                *(.text)     
        }
    
        .rodata ALIGN(4) : {         
                *(.rodata)     
        }
    
        .data ALIGN(4) : {         
                *(.data) 
        }       
    
        .got ALIGN(4) : {         
                *(.got)     
        }
    
        __boot_end = .;
    
        .bss ALIGN(16) : {         
                bss_start = .;         
                *(.bss)         
                *(COMMON)         
                bss_end = .;     
        }                       //ALIGN(16)表示16字节对齐
    
        .comment ALIGN(16) : {         
                *(.comment)     
        }
    
        stack_point = __boot_start + 0x00100000;     
        loader_size = __boot_end - __boot_start;     
        setup_size = setup_block_end - setup_block; 
    }
    

    参考

    Linux链接脚本学习–lds(写的比较基础的,可以作为入门看看)

    百度文库解释(前半部分还不错的)

    lds链接脚本*三篇博客(超级长的,排版不好的文章.不过很多人转了,可以看一下。)

  • 相关阅读:
    JedisConnectionException: java.net.ConnectException: Connection refused
    Mysql索引整理总结
    jstat命令总结
    Java死锁排查和Java CPU 100% 排查的步骤整理
    Spring-Session实现Session共享实现原理以及源码解析
    Spring-Session实现Session共享Redis集群方式配置教程
    Spring-Session实现Session共享入门教程
    Redis高可用集群-哨兵模式(Redis-Sentinel)搭建配置教程【Windows环境】
    jsp获取当前日期,包括星期几
    使用joda-time工具类 计算时间相差多少 天,小时,分钟,秒
  • 原文地址:https://www.cnblogs.com/AbeDay/p/5026843.html
Copyright © 2011-2022 走看看