VxWorks6.8提供了两套编译器:一套为diab系列编译器,为VxWorks传统的编译器;另一套为GNU系列的编译器,主要用来编译RTP工程。
RTP工程所使用的GNU系列编译环境可以使我们的基于嵌入式Linux的项目无缝地移植到VxWorks里面,在我们的实际使用中除了编译出来的文件大小比Linux的交叉编译工具链编译出来的文件大一倍左右外,基本上没什么区别了。刚开始的时候项目比较紧,基本上没有什么时间去优化这个问题,忙完一段时间后,项目告一段落,终于有时间要解决这个问题了,毕竟flash的成本也挺高昂的。
我们的代码是跨多个硬件平台、跨多个编译器和跨多个操作系统的,可以支持x86、ppc8548、ppc880、ppc8313、arm cortex a8、arm cortex a9等硬件平台、支持VC、VxWorks gnu系列编译器、Linux gcc系列编译器和支持xp、linux、VxWorks操作系统,就这样基本同一份代码,使用Linux的gnu交叉编译工具链编译出来的的ELF文件大小为3.5M左右,但使用VxWorks的gnu系列的交叉编译工具链并使用相同的编译优化选项编译出来的VXE文件(其实使用VxWorks
gnu系列编译器编译出来的可执行文件也是ELF格式文件,但在本文中为了跟Linux中编译出来的可执行文件做区别,我称呼使用VxWorks gnu系列的编译工具编译出来的文件为VXE文件,因为它以VXE作为其后缀)竟然有7M,整整大了一倍,同样是gnu系列的编译工具,为什么会有这么大的区别呢?通过相应的readelf文件查看ELF文件和VXE文件的各个段信息并做对比,发现VXE文件比ELF文件多了很多的rela段,rela段为重定位段,为什么VXE文件作为可执行文件它还需要那么多的重定位信息呢?ELF可执行文件是不需要这些信息的啊。这些rela段是不是多余的啊?刚开始我也觉得这些段是多余的,所以使用strip加-s参数分解VXE文件,文件大小确实可以达到跟ELF文件几乎相同大小,使用readelf工具查看段信息也确实把rela段删除了,但把经过strip加-s参数分解的VXE文件放到VxWorks板上运行时却出错,提示无法运行此VXE文件。懵了,看来要好好看看VxWorks的相关文档了。
看了vxworks_application_programmers_guide_6.8后我才明白,原来VxWorks对于RTP支持三种内存模式,第一种为无虚拟内存模式,第二种为Flat virtual memery model,第三种为Overlapped virtual memery model,RTP工程默认为第二种,即默认Flat virtual memery model,在此模式下,VXE文件使用重定位信息来快速地找到调用函数的入口地址,如果在此模式下删除了VXE文件的重定位信息,VXE文件肯定跑不起来了。但VxWorks的Overlapped
virtual memery model下的VXE文件无需使用重定位信息。知道这些信息后,我想我们是不是可以设置VxWorks RTP工作在Overlapped virtual memery model然后使用strip加-s参数分解VXE文件这样来减小VXE文件的大小来节省flash呢?vxworks_application_programmers_guide_6.8文档PART2证明了我的猜想是可行的。