您的位置:首页 > 其它

【GCC-ARM裸机开发随笔】----之lds链接脚本分析

2012-12-24 12:41 405 查看
随笔中记录的是笔者在Linux环境中用交叉工具链开发ARM裸机程序时遇到的一些问题和解决方法,主要是将解决问题的过程和一些小经验、小技巧记录下来。现在把一些感觉有点价值的内容搬到博客中供读者参考。





-----------------12.18-----------------

13:50

按照昨天的新方法,重写了一份较为通用的Makefile。可同时适用裸机和系统程序,同时使用交叉编译和本地编译。使用方法件Makefile中的说明。已测试可用。

15:23

http://blog.csdn.net/hulifox007/article/details/7406211

这个博客介绍的还行,里面提到了arm-linux-objdump的多个用法,可以查看一个程序里几个主要的段(.text.data等)。还提到objcopy出来的bin文件不包含.data段(这个段里包含已初始化的全局变量),尚不知此说法是否正确,有时间验证一下。如果真如此,博文里介绍了解决方法,通过设置.lds中的布局,把全局变量段(.data段)放到.text的位置即可。

16:04

.lds文件中的段名问题:程序中的.data段可以放在.text段名的范围中?如这样写:

.text : {

a.o(.text) b.o(.data)

}

猜想前面的.lds文件中出现的.text段名仅仅是个名字而已,不具有什么约束,他指定的位置可以放程序中的任意段,而不一定非是.text段。但我不确定。

http://blog.csdn.net/chenliujiang1989/article/details/7626833

这篇博文有点帮助,虽然没有明确说明我说的问题。

16:25

经过验证,15:23分记录的问题,关于objcopy只能拷贝代码段到.bin文件中的说法是不存在的,都可以拷贝。16:04的猜想是对的。

(注:后来搞清楚博文作者为什么那样说了,见我在http://blog.csdn.net/hulifox007/article/details/7406211这篇博文下面的评论)



16:40

总结一下。

试了一个程序,start.S设置一下堆栈就跳转至main。c文件为

int a=2;

int b=3;

int c[300];

const int d[200]={9,3,0};

int main()

{

*c=0;

return 0;

}

连接脚本连接顺序为:先start.o(.text),再 *(.text),再 *(.rodata),再*(.data),再*(.bss)。

全部编译后生成start.elf,使用“arm-linux-objdump -x start.elf >1.txt“命令,再查看生成的1.txt文件,发现各段的大小分别为:

第一个段{包含start.o(.text)和*(.text),即所有源码文件中的.text段}:0x40=64

第二个段{包含所有源码中的.rodata段}:0x320=800=200*4,对应数组d中的200个元素

第三个段{包含所有源码中的.data段}:0x08=8,对应a和b两个已初始化的变量

第四个段{包含所有源码中的.bss段}:0x4b0=1200=300*4,对应未初始化的变量数组c中的300个元素

再查看生成的start.bin文件的大小,是872,对应64+800+8,即前三个段长度之和。可见Makefile中运行"arm-linux-objcopy -O binary start.elf start.bin"之后,生成的bin文件中包含了除.bss段之外的所有段。

但这个说法也不绝对,.bss段也可以包含在bin文件中。只有在.lds中将.bss段安排在最后时,bin文件才不包含.bss段。而如果将.bss段安排在前面,比如安排在第二个段的位置,则编译后的bin文件大小就变成了 2072=872 + 1200,即所有段大小之和。(这个我已经试了,确实如此)。

事实跟我16:25猜想的一样。结论总结:bin文件中会包含除了.bss段之外的所有段,而不仅仅是.text段。一般都将当.bss段放在最后,以减小bin文件的体积。如果.bss段不在最后,则.bss段也将被包含在bin文件中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: