gcc链接脚本学习.doc
上传人:qw****27 上传时间:2024-09-12 格式:DOC 页数:6 大小:43KB 金币:15 举报 版权申诉
预览加载中,请您耐心等待几秒...

gcc链接脚本学习.doc

gcc链接脚本学习.doc

预览

在线预览结束,喜欢就下载吧,查找使用更方便

15 金币

下载此文档

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

GCC的连接脚本学习笔记来源:ChinaUnix博客日期:2009.04.2914:26(共有条评论)HYPERLINK"http://linux.chinaunix.net/bbs/thread-1109360-1-1.html"\t"_blank"我要评论连接脚本将我整整蒙了1天零一个上午,做了很多实验,看了人家不少例子代码勉强能驾驭了,让linker按照我想要的来处理,做个笔记。1,什么叫输入段,什么叫输出段不知道怎么回事,我对GCC系列的输入和输出两个单词总是进入思维死角,很简单就是inputsection和outputsection,这里不是说翻译的问题,我觉得是一种思考的方式的问题。我的问题就是:既然叫输入端,那输入什么?同理,输出的是什么?不知道其他人不会不理解这个问题,我自己的话是理解了不少时间了-v-所谓的输出段,是指生成的文件,例如elf中的每个段所谓的输入段,是指连接的时候提供LD的所有目标文件(OBJ)中的段。2,lma和vmalma=loadmemoryaddressvma=vitualmemoryaddress如果有研究过ADS的估计有印象,那里有个ROBASE和RWBASE和ZIBASE,也就是说,lma是装载地址,vma是运行地址,想搞清楚这两个问题,可以阅读一下《ARM学习报告(杜云海)》作者写的很好,将这个问题分析的很透澈。lma和vma只是GCC的叫法而已,其实原理是一样的。3,两个基本架构OUTPUT_FORMAT("elf32-littlearm","elf32-bigarm","elf32-littlearm")OUTPUT_ARCH(arm)一句话,照抄......因为我们没有修改的余地,都是系统默认的关键字。第一句指示系统可以有生成两种格式,默认是elf32-arm,端格式是littleendian4,ENTRY(__ENTRY)指定入口点,LD的手册说,ENTRYPOINT就是程序第一条执行的指令,但是,说老实话,我并不理解,因为这里跟我的理解矛盾了,首先,通常情况,系统需要一个初始化的STARTUP.S文件来初始化硬件,也就是bootloader的第一阶段了。那么很自然,入口点需要设置在这段代码的第一条指令中,那么正常运行的时候从第一条指令开始运行。所以这里设置了__ENTRY为入口点,这个在汇编代码中必须得先声明一下为全局,才能用,否则系统找不到。例如:.global__ENTRY但是问题是,如果我用同样的办法,设置另外一个不是第一条指令的入口点,LD并没有报错,但是问题来了,生成的文件和刚才设置入口点为__ENTRY的时候一模一样,这就蒙了,到底这个入口点是怎么回事?记得以前ADS的时候也碰到过entrypoint的问题,下载仿真的时候确实是自动跳转到entrypoint中运行。我想到的可能的原因,第一,生成elf文件并不是能直接用在嵌入式平台上面裸跑的,因为我们并没有操作系统,我们不需要elf文件头的那些指示信息提供给操作系统,指示系统怎么去加载文件,在嵌入式上面的完全没有那个必要,只需要将实际的代码提取出来,直接运行就OK,也就是objcopy的操作,所以我觉得,在裸奔的嵌入式系统上面,entrypoint是没有意义的,只需要指向整个代码最开始的指令就OK了。暂时我还是不能清晰的理解这个东西。先放下。以后碰到问题再分析。5,一个输出段的标准格式section[address][(type)]:[AT(lma)]{output-section-commandoutput-section-command...}[>region][AT>lma_region][:phdr:phdr...][=fillexp]前面也说了,所谓的输出段是指最终生成的文件里面的段,所以一个输出段就可以理解为最终文件里面的一个块,那么多个块合起来就是一个完成文件了。而每个小块又分别有什么文件来组成呢?那就是输入段了。我自己实际用到有下面的一些,其他暂时不会用。section_namevma:AT(lma){output-section-commandoutput-section-command...}[AT>lma_region]section_name根据ld手册说是有个确定的名字,其他没啥,自己添加一些新段也是可以的。默认的4个段是必须有的.text代码.rodata常量,例如字符串什么的.data初始化的全局变量.bss没有初始化的全局变量其实没什么,可以说,都是固定的,所以一句话,照抄。段名字后面紧跟的是vma,也就是这个段在程序运行的时候的地址,例如.text0x30000000:{*(.text)}表示的是代码的运行时地址为0x30000000假如你的ROM在0x0地址,程序放在