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

随笔中记录的是笔者在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文件中。

你可能感兴趣的:(【GCC-ARM裸机开发随笔】----之lds链接脚本分析)