.LDS 文件详解

2023-05-16

最近在研究uboot,红色部分为我加上的注解

 转载地址:

http://blog.chinaunix.net/space.php?uid=23373524&do=blog&cuid=2324182
lds文件与scatter文件相似都是决定一个可执行程序的各个段的存储位置,以及入口地址,这也是链接定位的作用。U-boot的lds文件说明如下:
      SECTIONS{
       ...
       secname start BLOCK(align)(NOLOAD):AT(ldadr)
            {contents}>region:phdr = fill
       ...
       }
       secname和contents是必须的,前者用来命名这个段,后者用来确定代码中的什么部分放在这个段,以下是这个描述中的一些关键字的解释。
       1、secname :段名
       2、contents :决定哪些内容放在本段,可以使整个目标文件,也可以是目标文件中的某段(代码段,数据段等)
       3、start:是段的重定位地址,本段连接(运行)的地址, 如果代码中有位置无关指令,程序运行时这个段必须放在这个地址上,start可以用任意一种描述地址的符号来描述。
       4、AT(ldar):定义本段存储(加载)的地址,如果不使用这个选项,则加载地址等于运行地址通过这个选项可以控制各个分段分别保存于输出文件中的不同位置
  例如:
       /*nand.lds*/
     SECTIONS {
      first 0x00000000:{head.o init.o}
      second 0x30000000:AT(4096) {main.o}
    
}
    
    以上,head.o放在0x00000000地址开始处,init.o放在head.o后面他的运行地址也是0x00000000,即连接地址和存储地址相同 (没有AT指定);main.o放在4096(0x1000是AT指定的存储地址)开始处,但他的运行地址在0x30000000,运行之前需要从0x1000(加载地址)复制到0x30000000(运行地址处),此过程也就需要读取flash,把程序拷贝到相应位置才能运行。这就是存储地址和运行的不同,称为加载时域和运行时域可以再.lds连接脚本文件中分别制定。
      编写好的.lds文件,在用arm-linux-ld连接命令时带-Tfilename来调用执行,如 arm-linux-ld  -Tnand.lds x.o y.o -o xy.o。也可用-Ttext参数直接指定连接地址如:
arm-linux-ld -Ttext 0x30000000 x.o y.o -o xy.o
      既然程序有了 两种地址,就涉及到一些跳转指令的区别。
下面1、2这一部分可以看韦东山的书,看看具体如何跳转的
     1)b  step: b跳转指令是相对跳转,依赖当前PC的值,偏移量是通过该指令本身的bit[23:0]算出来的,这使得使用b指令的不依赖于要跳到的代码的位置,只看指令本身。
     2)ldr pc,=step;该指令是一个伪指令编译后会生成以下代码:
     ldr pc,0x30008000
        <0x30008000>
                         step
     是从内存中的某个位置(step)读出数据并赋给PC,同样依赖于当前PC的值,但是偏移量是step的连接地址(运行时的地址),所以可以用它实现从Flash到RAM的程序跳转。
     (3)此外,有必要回味一下adr伪指令,U-boot中那段relocate代码就是通过adr实现当前程序是在RAM中还是在Flash中:
relocate:                        /*把u-boot重新定位到RAM*/
          adr  r0,_start      r0是代码的当前位置
adr指令:ADR伪指令--- 小范围的地址读取 

     ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。

 

ADR伪指令格式 :ADR{cond}   register, expr

地址表达式expr的取值范围:

    当地址值是字节对齐时,其取指范围为: +255  ~ 255B;

    当地址值是字对齐时,其取指范围为:   -1020 ~ 1020B;

是根据pc地址与相对偏移地址计算出来的,例如:现在是在片内ram中执行时,这时的r0的值为0x00000000,如果被从flash中load到外置的sdram(假设便宜地址为0x3000 0000)中,则此时r0的值为0x3000 0000

 /*adr伪指令,汇编器会自动通过当前PC的值得算出这条指令中“_start" 的值,执行到start时PC的值放到r0中:
       当此段在flash中执行时 r0=_start=0;当此段在RAM中执行时_start=_TEXT_BASE(在board/smdk2410/config.mk)中指定的值为0x33F80000,即U-Boot在把代码拷贝到RAM中去执行的代码段的开始*/
      ldr  r1,_TEXT_BASE  /*测试判断从Flash启动,还是从RAM启动此句执行的结果r1始终是0x33FF80000,因为此值是链接指定的*/
      cmp r0,r1     /*比较r0和r1,调试的时候不要执行重定位*/
 
 
 
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm");指定输出可执行文件elf格式,32位ARM指令,小端模式
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm) 指定输入平台为ARM
ENTRY(_start) 指定输出可执行文件的起始代码为_start
SECTIONS
{
 . = 0x00000000;   定位当前地址为0地址
 . = ALIGN(4);        代码以四字节对齐
 .text      :               指定代码段
 {
   cpu/arm920t/start.o (.text)  代码的第一个代码段
   *(.text)         其他代码段
 }
 . = ALIGN(4);
 .rodata : { *(.rodata) }  指定只读数据段
 . = ALIGN(4);
 .data : { *(.data) } 指定读写数据段
 . = ALIGN(4);
 .got : { *(.got) } 指定got段,got段式是uboot自定义的一个段,非标准段

 __u_boot_cmd_start = .;其赋值为当前位置,即起始位置
 .u_boot_cmd : { *(.u_boot_cmd) } u_boot_cmd段,Uboot把所有的uboot命令放在该段。
 __u_boot_cmd_end = .;把其赋值为当前位置,即结束位置
 . = ALIGN(4);
 __bss_start = .;  把__bss_start赋值为当前位置,即bss段的开始位置
 .bss : { *(.bss) }  ;指定bss段
 _end = .;;把_end赋值为当前位置,即bss段的结束位置
}

本文来自CSDN博客,转载请标明出处: http://blog.csdn.net/catamout/archive/2010/02/08/5298449.aspx
 

u-boot.lds文件详解

对于.lds文件,决定一个可执行程序的各个段的存储位置,以及入口地址,这也是链接定位的作用。这里以u-boot的lds为例说明uboot的链接过程。
首先看一下GNU官方网站上对.lds文件形式的完整描述:
SECTIONS {
...
secname start BLOCK(align) (NOLOAD) : AT ( ldadr )

  { contents } >region :phdr =fill
...
}
secname和contents是必须的,前者用来命名这个段,后者用来确定代码中的什么部分放在这个段,以下是对这个描述中的一些关键字的解释。
1、secname:段名
2、contents:决定哪些内容放在本段,可以是整个目标文件,也可以是目标文件中的某段(代码段、数据段等)
3、start:是段的重定位地址,本段连接(运行)的地址,如果代码中有位置无关指令,程序运行时这个段必须放在这个地址上。start可以用任意一种描述地址的符号来描述。
4、AT(ldadr):定义本段存储(加载)的地址,如果不使用这个选项,则加载地址等于运行地址,通过这个选项可以控制各段分别保存于输出文件中不同的位置。

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

main.o在生成的执行文件中的起始地址为4096,刚好是4k之后,s3c2440可以自动从nanflash加载4k的内容到内置的ram中运行


    以上,head.o放在0x00000000地址开始处,init.o放在head.o后面,他们的运行地址也是0x00000000,即连接和存储地址相同(没有AT指定);main.o放在4096(0x1000,是AT指定的,存储地址)开始处,但它的运行地址在0x30000000,运行之前需要从0x1000(加载地址处)复制到0x30000000(运行地址处),此过程也就需要读取 flash,把程序拷贝到相应位置才能运行。这就是存储地址和运行地址的不同,称为加载时域和运行时域,可以在.lds连接脚本文件中分别指定。

编写好的.lds文件,在用arm-linux-ld连接命令时带-Tfilename来调用执行,如
arm-linux-ld ?Tnand.lds x.o y.o ?o xy.o。也用-Ttext参数直接指定连接地址,如
arm-linux-ld ?Ttext 0x30000000 x.o y.o ?o xy.o。
既然程序有了两种地址,就涉及到一些跳转指令的区别。
ARM汇编中,常有两种跳转方法:b跳转指令、ldr指令向PC赋值。
要特别注意这两条指令的意思:
(1)       b step:b跳转指令是相对跳转,依赖当前PC的值,偏移量是通过该指令本身的    bit[23:0]算出来的,这使得使用b指令的程序不依赖于要跳到的代码的位置,只看指令本身。
(2)       ldr pc, =step :该指令是一个伪指令编译后会生成以下代码:
        ldr pc, 0x30008000
       <0x30008000>
                        step
    是从内存中的某个位置(step)读出数据并赋给PC,同样依赖当前PC的值,但是偏移量是step的连接地址(运行时的地址),所以可以用它实现从Flash到RAM的程序跳转。
(3) 此外,有必要回味一下adr伪指令,U-boot中那段relocate代码就是通过adr实现当前程序是在RAM中还是flash中:
         relocate:                          /* 把U-Boot重新定位到RAM */
         adr r0, _start                       /* r0是代码的当前位置 */
/* adr伪指令,汇编器自动通过当前PC的值算出这条指令中“_start"的值,执行到_start时PC的值放到r0中:

当此段在flash中执行时r0 = _start = 0;当此段在RAM中执行时_start = _TEXT_BASE(在board/smdk2410/config.mk中指定的值为0x33F80000,即u-boot在把代码拷贝到RAM中去执行的代码段的开始) */
    ldr r1, _TEXT_BASE                       /* 测试判断是从Flash启动,还是RAM */
/* 此句执行的结果r1始终是0x33FF80000,因为此值是链接指定的 */
    cmp r0, r1                     /* 比较r0和r1,调试的时候不要执行重定位 */
    结合u-boot.lds谈谈连接脚本。

OUTPUT_FORMAT("elf32&shy;littlearm", "elf32&shy;littlearm", "elf32&shy;littlearm")
            ;指定输出可执行文件是elf格式,32位ARM指令,小端
OUTPUT_ARCH(arm)
            ;指定输出可执行文件的平台为ARM
ENTRY(_start)
            ;指定输出可执行文件的起始代码段为_start.
SECTIONS

{
      . = 0x00000000               ; 定位当前地址为0地址
      . = ALIGN(4)                 ; 代码以4字节对齐
     .text :                       ;指定代码段
        {
           cpu/arm920t/start.o (.text)  ; 代码的第一个代码部分
          *(.text)                        ;其它代码部分
        }
        . = ALIGN(4)
        .rodata : { *(.rodata) }         ;指定只读数据段
        . = ALIGN(4);
        .data : { *(.data) }             ;指定读/写数据段
        . = ALIGN(4);

        .got : { *(.got) }        ;指定got段, got段式是uboot自定义的一个段, 非标准段
         __u_boot_cmd_start = .  ;把__u_boot_cmd_start赋值为当前位置, 即起始位置
        .u_boot_cmd : { *(.u_boot_cmd) }          ;指定u_boot_cmd段, uboot把所有的uboot命令放在该段.
         __u_boot_cmd_end = .                          ;把__u_boot_cmd_end赋值为当前位置,即结束位置
        . = ALIGN(4);
         __bss_start = .                                       ; 把__bss_start赋值为当前位置,即bss段的开始位置
        .bss : { *(.bss) }                        ; 指定bss段
         _end = .                   ; 把_end赋值为当前位置,即bss段的结束位置

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.LDS 文件详解 的相关文章

  • ROS的package_xml文件详解

    属性 xff1a package xml详解 1 1软件包 xff08 package xff09 清单 xff08 manifest xff09 是一个名为 package xml 2 的 XML 文件 xff0c 必须包含在任何兼容 c
  • adlds文件服务器,修改 AD LDS 配置

    修改 AD LDS 配置 2021 6 1 本文内容 适用于 xff1a Exchange Server 2013 在将 边缘 传输服务器订阅到 Exchange 组织之前 xff0c 可以使用位于 env xff1a ExchangeIn
  • chrome扩展:manifest.json文件详解

    manifest json是扩展的配置文件 xff0c 指明了扩展的各种信息 一个manifest json格式如下 xff1a 必须的字段 3 个 34 name 34 34 MyExtension 34 扩展名称 34 version
  • Manifest文件详解

    一 关于AndroidManifest xml AndroidManifest xml 是每个android程序中必须的文件 它位于整个项目的根目录 xff0c 描述了package中暴露的组件 xff08 activities servi
  • /etc/resolv.conf文件详解

    etc resolv conf它是DNS客户机配置文件 xff0c 用于设置DNS服务器的IP地址及DNS域名 xff0c 还包含了主机的域名搜索顺序 该文件是由域名解析器 xff08 resolver xff0c 一个根据主机名解析IP地
  • GAZEBO 中 sdf文件详解

    转载自 xff1a https blog csdn net weixin 44900096 article details 103017522 GAZEBO 中 sdf文件详解 木木木一 2019 11 11 20 49 21 2166 收
  • CMakeList.txt文件详解

    1 整体结构 CMakeList txt文件必须遵循以下的格式 xff1a 所需的CMake版本 xff08 cmake minimum required xff09 软件包的名称 xff08 project xff09 查找构建所需要的其
  • GAZEBO 中 sdf文件详解

    GAZEBO 中 sdf文件详解 1 model模型 一个模型数据库会拥有的文件 xff08 1 xff09 database config xff1a 有关数据库的元数据 xff0c 从CMakeList自动填充 本地不需要 xff08
  • 【ORB_SLAM2 CMakeLists.txt 文件详解】

    文章目录 ORB SLAM2 CMakeLists txt 文件详解 set CMAKE LIBRARY OUTPUT DIRECTORY PROJECT SOURCE DIR lib add library PROJECT NAME SH
  • ROS笔记(一)xxx.launch文件详解

    ROS笔记 一 xxx launch文件详解 launch文件是ROS中用于同时启动多个节点的重要文件 在大型的ROS项目中使用频繁 所以掌握其主要元素与属性对ROS系统的应用至关重要 xff1a launch标签 元素 说明launch拓
  • Qt pro文件详解

    文章目录 pro文件中的配置信息QT配置项 已剪辑自 http c biancheng net view vip 9661 html 默认情况下 xff0c 每个 Qt 项目都包含一个后缀名为 pro 名称和项目名相同的文件 xff0c 我
  • ROS 中package.xml文件详解01

    package xml文件时每一个ros包都要有的一个文件 xff0c 也是必须要包含的一个文件 1 最简单的xml文件 span class token operator lt span package format span class
  • Px4 ULog文件详解

    Px4 ULog文件详解 简介数据类型文件组织文件头定义段消息标记位消息格式定义消息信息消息复合信息消息参数消息 数据段订阅消息取消订阅消息日志数据消息字符串消息同步消息丢失 附录 简介 ULog 是用于记录数据的文件格式 xff0c 该格
  • Dockerfile文件详解

    什么是dockerfile Dockerfile是一个包含用于组合映像的命令的文本文档 可以使用在命令行中调用任何命令 Docker通过读取Dockerfile中的指令自动生成映像 docker build命令用于从Dockerfile构建
  • 激光雷达(LDS)技术原理解释及实现过程

    一 激光雷达 xff08 LDS xff09 简介 1 激光雷达应用举例 xff1a 现在自主移动机器人领域非常火爆 xff0c 无人车 无人飞机 水下机器人 仓储机器人 扫地机等应用层出不穷 激光雷达传感器是地面移动机器人的标配 xff0
  • ROS中使用激光雷达HLS-LFCD LDS(Neato XV-11)

    本例激光雷达 HLS LFCD2 参考资料 xff1a https blog csdn net jacka654321 article details 82916688 接线 新款 CP2102模块 USB to TTL USB转串口模块U
  • 【ROS】launch文件详解

    参考 xff1a https www cnblogs com fuzhuoxin p 12588402 html 在节点少 xff0c 程序小的情况下可以一个一个节点来启动 xff0c 测试运行效果 xff1b 但是当工程规模大 xff0c
  • web.xml文件详解

    前言 一般的web工程中都会用到web xml web xml主要用来配置 可以方便的开发web工程 web xml主要用来配置Filter Listener Servlet等 但是要说明的是web xml并不是必须的 一个web工程可以没
  • 7. 从0学ARM-GNU伪指令、代码编译,lds使用

    嵌入式工程师到底要不要学习ARM汇编指令 arm学习文章汇总 到底什么是Cortex ARMv8 arm架构 ARM指令集 soc 一文帮你梳理基础概念 科普 关于ARM指令用到的IDE开发环境可以参考下面这篇文章 1 从0开始学ARM 安
  • GNU 链接脚本LDS介绍

    前言 程序的从C语言代码变成可以在目标机器上执行额文件 可以分为如下步骤 编译 预编译 将宏定义等转义编译 将C语言变成目标文件 o档案 编译 汇编 将预编译过后的目标变为目标文件 链接 合并多个目标文件 o a 等为最终的可执行文件 LD

随机推荐

  • 网络通信2—UDP 模型程序编写步骤(参照 Ubuntu 16.04 版本)

    UDP 模型程序编写步骤 一 UDP基础模型 服务器流程 step 1 xff1a 创建 socket 套接字接口并判断 sockfd 61 socket AF INET SOCK DGRAM 0 if sockfd 61 61 1 per
  • switch 中 break 和 continue 的区别

    1 break 用来退出 switch xff0c continue 本身是不能用在 switch 里的 xff0c 他必须结合循环来用 xff0c 表示跳过本次循环 2 switch 的 case 语句最后如果没有加 break cont
  • 立即数

    一 概念 xff1a 通常把在 立即寻址方式 指令中给出的数称为立即数 二 判断步骤 xff1a 把数据转换成二进制 xff0c 从低到高写成 4 个一组 xff0c 最高位不够一组的补 0 xff1b 数 1 的个数 xff0c 如果大于
  • 位、字节、char、int(32位系统) 之间的关系

    一 概念 xff1a 位 xff08 bit xff09 xff1a 计算机中最小的数据单位 每一位的状态只能是0或1 字节 xff08 byte xff09 xff1a 存储空间的基本计量单位 xff0c 8 个二进制位构成1个字节 1
  • C语言中的那些宏

    DATE 进行预处理的日期 xff08 Mmm dd yyyy 形式的字符串文字 xff09 FILE 代表当前源代码文件名的字符串文字 LINE 代表当前源代码中的行号的整数常量 TIME 源文件编译时间 xff0c 格式微 hh xff
  • 任务栈简单入门

    最近又把两本进阶书看了一遍 xff0c 但总感觉好记性不如烂笔头 xff0c 所以还是决定通过博客记录一下 xff0c 我们将分两篇来全面深入地记录Activity 启动模式与任务栈的内容 android任务栈简单了解 1 android任
  • VS2010里函数枚举

    一 cout函数 说明 xff1a 调用该函数必须申明头文件 include lt iostream gt 同时声明后面必须使用 using namespace std 正确书写为 xff1a include lt iostream gt
  • I_O—标准 I_O 实验

    一 测试标准 I O 一次可以同时打开多少个文件 1 实验思路 xff1a 利用循环同时打开文件 xff0c 直到不能打开 2 代码如下 xff1a 二 fgetc 和 fputc 实现拷贝文件并输出文件行数 1 实验思路 xff1a 打开
  • Source Insight 配色方案

    Source Insight 对于程序员来说应该不陌生 xff0c 当然一个个性化的编程界面也会让自己赏析悦目 xff0c 下面就将个人的界面设置分享一下 xff1a 一 背景色设置 1 选择 Options Preferences 2 选
  • Linux 网络——交换机不能用两根网线相连

    同一个局域网所有的交换机之间可以用网线串联起来 xff0c 但绝对不能使任意 gt 61 2个交换机形成环路 xff0c 否则局域网内将形成广播风暴 xff0c 所用局域网内的用户都将不能上网 例如局域网内的交换机可以使用如下相连 xff1
  • GDB 知识点——基础操作

    Linux C 中的 GDB 调试使用 xff1a 1 GDB 的主要功能 xff1a 1 启动被调试程序 2 让被调试的程序在指定的位置停住 3 当程序被停住时 xff0c 可以检查程序状态 xff08 如变量的值 xff09 2 检查
  • 员工管理系统(C 语言)——项目说明

    项目名称 xff1a 员工管理系统 项目目的 xff1a 1 实现简单的公司对员工信息的管理 2 通过项目锻炼实现逻辑转换为代码的能力 3 利用函数封装实现项目过程中的逻辑过程以及需求功能的实现 4 学会数据库的操作以及网络通信 5 强化代
  • 员工管理系统(C 语言)——客户端解析

    源码下载地址 xff1a https download csdn net download wenfei11471 10477504 客户端功能 xff1a 1 运行时先测试是否能连通服务器 xff08 不畅通如下图所示 xff09 xff
  • 员工管理系统(C 语言)——服务器解析

    源码下载地址 xff1a https download csdn net download wenfei11471 10477504 服务器功能 xff1a 1 运行时主界面 xff08 服务器启动后 xff0c 只有管理员下线 xff0c
  • 排序——选择排序、冒泡排序和快速排序比较

    一 选择排序思路 xff1a 1 以 int 类型为例 2 拿第一个数与后面数相比较 xff0c 如果比后面的数大则交换 3 拿第二个数与后面的数比较 xff0c 如果比后面的数大则交换 4 直到比较到倒数第二个数 xff0c 最后一个数不
  • C 语言中 const 与指针的结合使用

    请区分一下几种指针的区别 1 const int p 2 int const p 3 int const p 4 const int const p 5 const int const p 解析 xff1a 1 const int p 中
  • Ubuntu16.04上安装百度网盘后打不开

    现在百度网盘推出了Linux版本 xff0c 也有Ubuntu下安装的deb文件 xff0c 但是我在Ubuntu上安装后却打不开 xff0c 报错 baidunetdisk crashed with SIGABRT in gnu cxx
  • C/C++的“文件包含”处理时头文件被重复包含的问题探究及解决方法(用最简单的例子进行说明)

    这篇博文是博文https blog csdn net wenhao ir article details 125668051的配套博文 头文件被重复包含是下面这样的现象 xff1a A文件里包含了C文件 xff0c B文件里也包含了C文件
  • BIN,BCD,ASCII码分别对应的Hex(16进制)数

    BIN BCD ASCII码分别对应的Hex xff08 16进制 xff09 数 以十进制的 56 为例 BIN 码 对应二进制数为 0011 1000对应Hex数据为 0x38BIN码就是二进制数 xff1b 压缩BCD 码 对应二进制
  • .LDS 文件详解

    最近在研究uboot xff0c 红色部分为我加上的注解 转载地址 xff1a http blog chinaunix net space php uid 61 23373524 amp do 61 blog amp cuid 61 232