嵌入式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链接脚本*三篇博客(超级长的,排版不好的文章.不过很多人转了,可以看一下。)

嵌入式Linux-linux连接脚本的更多相关文章

  1. 使用C#给Linux写Shell脚本

    在这个逼格决定人格,鄙视链盛行的年头,尤其是咱们IT界,请问您今天鄙视与被鄙视的次数分别是多少?如果手中没有一点压箱的本事,那就只有看的份了.今天我们也要提升下自己的格调,学习些脑洞大开的东西,学完之 ...

  2. 嵌入式系统Linux内核开发工程师必须掌握的三十道题(转)

    嵌入式系统Linux内核开发工程师必须掌握的三十道题 如果你能正确回答以下问题并理解相关知识点原理,那么你就可以算得上是基本合格的Linux内核开发工程师,试试看! 1) Linux中主要有哪几种内核 ...

  3. 构建嵌入式小型Linux系统

    构建嵌入式小型Linux系统 摘要:用buildroot构建x86的交叉编译工具链:裁减linux内核,尽可能做到最小:手工构建根文件系统:安装qemu虚拟机,仿真新配置的Linux系统:为新配置的L ...

  4. Python编写的Linux网络设置脚本,Debian Wheezy上测试通过

    hon编写的Linux网络设置脚本,Debian Wheezy上测试通过       阿里百川梦想创业大赛,500万创投寻找最赞的APP 技术细节参见Linux网络设置高级指南 注意事项参见程序注释 ...

  5. linux开机启动脚本

    linux开机启动脚本 linux 开机启动脚本 用户自定义开机程序(/etc/rc.d/rc.local) 操作最简单,方便.每次都自己启动PHP啊,Nginx啊 烦死了,其他方式还要弄shell啊 ...

  6. linux安全关机脚本

    linux安全关机脚本 在断电4分钟后判断关键 目的:在断电以后服务器连接UPS,UPS最多只能支持5分钟也会没电,所以在这里做个判断,如果断电4分钟后,市电还没来就关机. 以下两个设备为两个下路由器 ...

  7. linux下添加自动启动项,linux 开机自动启动脚本方法

    #service servicename status是当前状态#chkconfig --list servicename是查看启动状态,也就是是否开机自动启动 首先写好脚本,如 mysql,把它放到 ...

  8. Linux开机自启动脚本的总结

    一.在/etc/rc.local中添加 如果不想将脚本粘来粘去,或创建链接什么的, 则: step1. 先修改好脚本,使其所有模块都能在任意目录启动时正常执行; step2. 再在/etc/rc.lo ...

  9. 详解Linux交互式shell脚本中创建对话框实例教程_linux服务器

    本教程我们通过实现来讲讲Linux交互式shell脚本中创建各种各样对话框,对话框在Linux中可以友好的提示操作者,感兴趣的朋友可以参考学习一下. 当你在终端环境下安装新的软件时,你可以经常看到信息 ...

随机推荐

  1. Service Oriented Architecture

    What is Service Oriented Architecture (SOA)? There have been so many interpretations of this through ...

  2. bzoj1930

    一开始我觉得这不是一个弱弱的费用流吗? 每个豆豆拆点,入点出点随便连连 由于肯定是DAG图,边权为正的最大费用肯定能增广出来 于是我们只要跑总流量为2的最大费用最大流不就行了吗 但是 这样会TLE,因 ...

  3. 小试.NET代码保护软件(代码混淆、加密)

    有着微软人性化的开发工具VISUAL STUDIO和MSDN详尽的帮助,.NET 的开发效率的确高. 但是由于.NET同JAVA一样都采用中间语言.虚拟机/SDK等诸多特质,而且高等语言的类库编码规范 ...

  4. 一个TextView使用不同的颜色

    一个TextView使用不同的颜色: textview中首先需要已经有内容了 public static void ColorFormatTextView(TextView tv,int color, ...

  5. NSArray和NSMutableArray的copy和MutableCopy

    NSArray: //main.m #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { ...

  6. scp linux远程拷贝和本地拷贝命令

    linux远程拷贝和本地拷贝命令   一.linux对linux 远程拷贝   scp命令    scp 文件名  root@远程ip:/路径/    将本地home目录下的test.tar的文件拷贝 ...

  7. LightOJ 1245 Harmonic Number (II) 水题

    分析:一段区间的整数除法得到的结果肯定是相等的,然后找就行了,每次是循环一段区间,暴力 #include <cstdio> #include <iostream> #inclu ...

  8. 从 NavMesh 网格寻路回归到 Grid 网格寻路。

    上一个项目的寻路方案是客户端和服务器都采用了 NavMesh 作为解决方案,当时的那几篇文章(一,二,三)是很多网友留言和后台发消息询问最多的,看来这个方案有着广泛的需求.但因为是商业项目,我无法贴出 ...

  9. HTML5 SSE自动推送

    前端页面: <!doctype html> <html> <head> <meta charset="UTF-8"> <tit ...

  10. git 实用命令

    git 覆盖本地修改 ,git 放弃本地修改,强制更新 git fetch --all git reset --hard origin/master git fetch 只是下载远程的库的内容,不做任 ...