lds链接脚本基础与例子分析
1.基础
(1)段
.data
段包含初始值非0的全局变量(不管静态还是非静态).rodata
段包含被const修饰的初始值非0的全局变量.bss
段包含初始值为0或未初始的全局变量(不管有没有const修饰,也不管是静态还是非静态)局部变量保存在栈中
注:有的编译器会将没有初始化的变量保存在COMMON
段,等到链接时再将其放入到bss
段。.text
段保存代码
(2)指定不同段的地址(不用链接脚本)
编译过程
编译: arm-linux-gcc -c -o led_on.o led_on.S #或led_on.c链接: arm-linux-ld -Ttext 0 led_on.o -o led_on.elf生成bin: arm-linux-objcopy -o binary -S led_on.elf led_on.bin
生成反汇编: arm-linux-objdump -D led_on.elf > led_on.dis
arm-linux-objcopy
复制一个目标文件的内容到另一个文件中,可以使用不同于源文件的格式来输出目的文件,即可以进行格式转换。常用arm-linux-objcopy
将ELF
格式的可执行文件转换为bin
二进制文件。
arm-linux-objcopy -O binary -S elf_file bin_file-O:使用指定的格式来输出文件-S:不从源文件中复制重定位信息和符号信息到目标文件中去
arm-linux-objdump
显示二进制文件信息,常用来查看反汇编代码。
//ELF转为反汇编
arm-linux-objdump -D elf_file>dis_file
//二进制转为反汇编
arm-linux-objdump -D -b binary -m arm bin_file > dis_file-D:反汇编所有段-b:指定目标码格式,不是必须的。可通过arm-linux-objdump -i查看支持的目标码格式-m machine:指定反汇编目标文件时所使用的架构,当待反汇编文件本身没有描述架构信息的时候,这个选项很有用。
arm-linux-ld
-Ttext startaddr #直接指定代码段地址
-Tdata startaddr #直接指定数据段地址
-Tbss startaddr #直接指定bss段地址
例子
arm-linux-gcc -c -o link.o link.s
arm-linux-ld -Ttext 0x00000000 link.o -o link_elf_0x00000000//启动后PC=0x00000000
arm-linux-ld -Ttext 0x30000000 link.o -o link_elf_0x30000000//启动后PC=0x30000000
- 只指定代码段的地址,则数据段和bss段紧跟着代码段存放
(3)链接地址和加载地址
- 链接地址是程序实际运行的地址(内存)
- 加载地址指的是程序编译后的存放地址(Flash)
(4)链接脚本格式
- 链接脚本由一系列命令组成,每个命令由一个关键字或一条对符号的赋值语句组成,命令间用分号分开。
- 若文件名或格式名内包含分号,需用单引号引用起来
(5)链接脚本的语法
SECTIONS {...secname start ALIGN(align) (NOLOAD) : AT ( ldadr ){ contents } >region :phdr =fill...
}
secname
和contents
是必须的,前者用来命名这个段,后者用来确定代码中的什么部分放在这个段中。start
:段重定位地址,也称为VMA
,即运行地址。如果代码中有位置相关的指令,程序在运行时,这个段必须放在这个地址上。ALIGN(align)
:虽然start
指定了运行地址,但是仍可以使用BLOCK(align)来指定对齐的要求一这个对齐的地址才是真正的运行地址。(NOLOAD)
:用来告诉加载器,在运行时不用加载这个段。这个选项只有在有操作系统的情况下才有意义。AT (ldadr)
:指定这个段在编译出来的映象文件中的地址,称为LMA
,即加载地址。若不指定默认加载地址等于运行地址。通过这个选项,可以控制各段分别保存在输出文件中不同的位置。>region :phdr =fill
:没用到,不作介绍。
(6)简单脚本命令
ENTRY(SYMBOL)
: 将符号SYMBOL的值设置成入口地址(执行的第一条指令的地址)。- 入口地址设置的方法还有(按优先级高低):
- ld命令行的
-e
选项 - 链接脚本的
ENTRY(SYMBOL)
命令 - 如果定义了
start
符号,使用start
符号值 - 如果存在
.text section
, 使用其第一字节的位置值 - 使用值0
- ld命令行的
- 入口地址设置的方法还有(按优先级高低):
INCLUDE filename
:包含其他名为filename的链接脚本。脚本搜索路径由-L选项指定。. = ALIGN(4)
:代码以4字节对齐LOADADDR(.data)
:取data
段的LMA
ADDR(.data)
:取data
段的VMA
(7)C语言相关
对C语言符号地址的赋值
在C文件内定义的全局变量可以在链接脚本内被赋值,此处赋值的意思是更改变量的地址。
/* a.c */
#include <stdio.h>
int a = 100;
int main(void)
{printf( "&a=0x%p ", &a );return 0;
}/* a.lds */
a = 3;/* 不使用链接脚本 */
gcc -Wall -o a-without-lds a.c
&a = 0x8049598/* 使用链接脚本 */
$ gcc -Wall -o a-with-lds a.c a.lds
&a = 0x3
将变量/函数放入指定段中
__attribute__((section("section_name")))
:将作用的函数或数据放入指定名为"section_name"对应的段中。
变量:
const int descriptor[3] __attribute__ ((section ("descr"))) = { 1,2,3 };
long long rw[10] __attribute__ ((section ("RW")));
函数:
void Function_Attributes_section_0(void) __attribute__ ((section ("new_section"))); //声明时指定段
void Function_Attributes_section_0(void)
{static int aStatic =0;aStatic++;
}
链接脚本变量
链接脚本中定义的变量可以在C语言中使用extern
关键字声明并使用
2 链接脚本例子
(1)例1:基础链接脚本
SECTIONS {outputa 0x10000 : //该section的VMA是0x10000{all.o //all.o文件的所有sectionfoo.o (.input1) //foo.o文件的所有(一个文件内可有多个同名section).input1 section}outputb : //该section的VMA是当前定位器符号的修调值(对齐后){foo.o (.input2)foo1.o (.input1)}outputc : //将非all.o、foo.o、foo1.o文件的. input1 section和.input2 section放入输出outputc section内{*(.input1)*(.input2)}
}
(2)例2
编译时使用链接脚本:
arm-linux-ld -Ttimer.lds -o timer_elf head.o init.o interrupt.o main.o
timer.lds
如下
SECTIONS{. = 0X30000000;.text : {*(.text)}.rodata ALIGN(4) :{*(.rodata)}.data ALIGN(4) :{*(.data)}.bss ALIGN(4) :{*(.bss) *(COMMON)}
}
①第2行设置运行地址为0x30000000
。
.
为定位器符号,不指定默认为0。存放了某个段后,定位器符号会往后移动这个段的大小长度,所以后面rodata
段的地址为0X30000000
+.text
段大小(还要四字节对齐)
②第3行定义了一个名为.text
的段,它的内容为*(.text)
, 表示所有输入文件的代码段。这些代码段被集合在一起,起始运行地址为0x30000000
。
③第4行定义了一个名为.rodata
的段,在输出文件timer_elf
中,它紧挨着.text
段存放。其中的ALIGN (4)
表示起始运行地址为4字节对齐。假设前面.text
段的地址范围0x30000000~0x300003f1,则.rodata
段的地址是4字节对齐后的0x300003f4。
④第5、6行的含义与第4行类似。
(3)例3:输出SECTION的LMA修改
SECTIONS
{.text 0x1000 : { *(.text) _etext = . ;}.mdata 0x2000 : AT ( ADDR (.text) + SIZEOF (.text) ){_data = . ;*(.data);_edata = . ;}.bss 0x3000 :{_bstart = . ;*(.bss) *(COMMON) ;_bend = . ;}
}
程序中可定义上面定义的地址:
extern char _etext, _data, _edata, _bstart, _bend;
.mdata 0x2000 : AT ( ADDR (.text) + SIZEOF (.text) )
:生成的bin文件中mdata
段紧跟着text
段,但是加载到内存时,mdata
段在0x2000
处。(若LMA不紧接着上一个,生成的bin文件会很大,中间都是空洞,不方便烧写)
再来看一个链接脚本片段:
.data 0x30000000 : AT(0x800) #不指定默认LMA等于VMA
- 对应的bin文件的
data
段会烧写在flash的800处,程序运行时,代码中实现从0x800(加载地址)复制代码到0x30000000(链接地址)
lds链接脚本基础与例子分析相关推荐
- 嵌入式Linux系统中的.lds链接脚本基础
from:http://www.embeddedlinux.org.cn/html/xinshourumen/201203/04-1989.html 连接脚本的格式 ================= ...
- Linux下的lds链接脚本详解
一. 概论 每一个链接过程都由链接脚本(linker script, 一般以lds作为文件的后缀名)控制. 链接脚本主要用于规定如何把输入文件内的section放入输出文件内, 并控制输出文件内各部分 ...
- linux下lds链接脚本详解
转载自:http://linux.chinaunix.net/techdoc/beginner/2009/08/12/1129972.shtml 一. 概论 每一个链接过程都由链接脚本(linker ...
- makefile使用.lds链接脚本以及 $@ ,$^, $, 解析
先来分析一个简单的.lds链接脚本 例1,假如现在有head.c init.c nand.c main.c这4个文件: 1.1 首先创建链接脚本nand.lds: 1 SECTIONS { 2 fir ...
- Rt-thread [三] link.lds链接脚本详解
Rt-thread [三] link.lds文件详解 前言 程序编译流程 什么是链接 基本概念 RT-thread stm32f407 link.lds链接脚本详解 资料 前言 开一个专题,记录自 ...
- uboot.lds链接脚本分析
LDFLAGS += -Bstatic -T /board/smdk2410/u-boot.lds -Ttext 0x33F80000中-Ttext 0x33F80000是指定代码段text的首地址 ...
- Linux下的lds链接脚本二
对于.lds文件,它定义了整个程序编译之后的连接过程,决定了一个可执行程序的各个段的存储位置.虽然现在我还没怎么用它,但感觉还是挺重要的,有必要了解一下. 先看一下GNU官方网站上对.lds文件形式的 ...
- S3C2440 lds链接脚本解析
1. SECTIONS到底意味着什么 在一个裸版程序里面含有*.lds文件,而lds文件意味着如果你的程序烧录在nandflash,那在nandflash的内存将根据lds文件指定偏移来分布,下面从 ...
- linux 链接脚本,Linux下的lds链接脚本简介(一)
每一个链接过程都由链接脚本(linker script, 一般以lds作为文件的后缀名)控制. 链接脚本主要用于规定如何把输入文件内的section放入输出文件内, 并控制输出文件内各部分在程序地址空 ...
最新文章
- 解决 python pip install安装速度慢| 版本低|跨过个别错误包
- springboot security 权限校验_十二、SpringBoot 优雅的集成Spring Security
- php和js搜索框,利用PHP+JS实现搜索自动提示(实例)_php技巧
- rhcs实现mysql高可用。仲裁磁盘
- 再读simpledb 之 SQL语句解析(1)
- 如何获得对方IP地址
- 《Labeled Data Generation with Inexact Supervision》 KDD-2021 论文阅读
- 大学英语综合教程四 Unit 1至Unit 8 课文内容英译中 中英翻译
- 二极管工作原理讲解(转载)
- C#调试AutoCAD自动加载图形和dll库文件
- Excel2——在同一个图中如何绘制多条曲线并标注图例
- python鼠标监听_用Python监听鼠标和键盘事件
- RRC协议学习—系统信息(SI)
- 医院管理信息系统 HIS EMR PACS LIS
- linux的基础简答题,Linux认证考试试题及答案「简答题」
- EMPIRE: LUPINONE实战演练
- PASCAL VOC2012 数据集讲解与制作自己的数据集
- 计算机word缩小表格,word排版 文件等比例缩小 word表格等比例缩小
- 公众号“机器修行”开篇·致读者
- AIOT产业技术全景结构-数字化架构设计(8)