简述构建gcc交叉编译平台

目标:编译出可以在arm板上运行的可执行文件

 

原理:一般情况下编译器编译出来的程序只能运行在与当前系统兼容的环境中:例如visual++编译出的程序运行在安microsoft的系统中。

 

问题 1:为什么visual生成的程序不能在arm上跑?

我们知道程序是由一条条的指令结合数据构成的,系统运行程序即是cpu在执行这些指令,cpu执行指令有取指、译码、执行等过程。

取值就是ldr一条指令到相关寄存器这个不必多解释,问题点在译码和执行上, 略举一例:

ldrb r3,[r1] #r1的内容指向的内存地址处取出一个字节的数据存到r3

上条指令的机器码是e5d1300032bitcpu得到e5d13000进行译码,重点开始了cpu怎么知道这32bit代表什么意思呢?说白了,这个代表什么意思

不是你说的算,也不是我说的算。它是由芯片制造商决定的,例如上述的e5d13000是一条arm指令,该如何执行它?arm公司早就制定了一套规范并在

芯片逻辑里面设定好了。执行的结果就是从r1的内容指向的内存地址处取出一个字节的数据存到r3

请设想一下如果intelcpu在执行e5d13000时会是什么结果呢?显然结果是未定义的,因为intelcpu压根不认识这条指令,它从未制定这样的规范。

说的通俗一点就像你对别人说"你好"人家大概可以听懂。如果你对蜜蜂说"你好",蜜蜂会知道是个啥意思?

关于问题1的解释不只是上面的这些,鄙人才疏学浅就只解释这么多了~

 

问题 2:如何生成可在arm板运行的程序?

设想方案:类推一下,例如我们可以在安装有arm芯片的操作系统中构造一个编译器,由该编译器编译出来的程序可以直接运行在arm环境中,它的好处是省得折腾。

这是一个设想,至少目前还没有听过有谁这样做,因为arm芯片的主频相比intel系列的cpu来说是很低的,构造这样一个编译器在arm上编译程序恐怕得不偿失。

目前的做法是构建一个gcc交叉编译平台(好辛苦终于说到正题上来了O(∩_∩)O~

gcc交叉编译平台也可以称之为GCC(GNU Compiler Collection),援引一段很官方的话"GCC是现阶段被广泛使用的开放源码的编译器, 它支持多种高级语言(c,c++,

fortran,java,ada),同时支持多种处理器(alpha, arm, intel 386, adm, IA-64....)"这段官腔的意思说白了就是用我这套编译工具可以编译c,c++等语言的源代码,编译

出来的目标执行文件根据你的配置可以跑在特定芯片的系统上(alpha, arm, intel等等)

例如,我想编译一段c语言的源代码,目标文件可以运行在arm上。编译器该如何做呢?

大致过程应该是:预编译处理(一些宏定义\if结构等等)->c编译器编译(.c变成.s即生成汇编文件)->汇编编译器编译(.s生成机器码)->链接器链接(生成elf格式的文件)

上述的每个过程都是不可小觑的,c编译器在编译.c源文件的时候生成的汇编代码需满足基本2点:

1、是生成的汇编指令是符合arm指令集的,当然编译器也会制定一些伪指令,但伪指令实际也是由指令集中的指令构成的。

2、在将.c文件的逻辑翻译成汇编代码是必须符合pcs(procedure call standard)即过程调用标准,armpcs简称

apcsapcs仅仅是一套标准,简单讲是一套有关cpu内部寄存器使用的规范,它不会在芯片逻辑电路上有任何体现,满足该标准可以让你的程序不出问题(O__O"…当然

不算上程序本身的bug),并且可以同其它满足该标准的程序兼容(也就是可以互访)。也许你说我从未听过apcs,写程序时也从未考虑过要去符合apcs,那为什么我的程序

没出问题呢? 我告诉你是你运气好你会相信吗?如果是我的话我肯定不信.....这个问题的答案我想上面已经说了,是因为C编译器在翻译成汇编代码的时候已经帮我们考虑好了,也就是它帮你做好了。那么如果你直接写一段汇编程序,这个标准就必须由你亲自来遵守!扯远了~

 (关于apcs请参考:http://blog.csdn.net/keyboardota/article/details/6799054

 

言归正传,GCC是以一系列的组件源码方式提供给大家下载,下完了需要针对arm板编译,安装之后我们的交叉编译器才算是ok~

完成上述的过程首先需要选择一个平台:Linux, unix, Cygin, MinGW等。Cygin是一个运行在windows上的Unix虚拟机,MinGW与之相似是Linux虚拟机。

上述平台相似点是都安装有GNU makegcc(在安装CyginMinGW时注意要必须安装这两个组件),强调下这里的gcc是本地gcc编译器即它编译出来的程

序只可以跑在本地兼容系统,例如Linuxgcc编译的程序跑在Linux系统(不要试图以为它可以直接运行在arm板上哦O(∩_∩)O~)。

我们总的方针是用这个本地gcc,编译出一个针对arm的编译器(直白点就是一个程序)称之为arm-elf-gcc交叉编译器,再由这个交叉编译器编译逻辑源文件。

由交叉编译器产出的结果就可以在arm板上跑了。

问题是如何由本地gcc来编译产生一个交叉编译器呢?前面说了GNU Compiler Collection是开发源码的编译器,所以我们用本地gcc去编译这些源代码就可以了。

大致过程是:1、下载binutils源代码,用本地gcc编译出针对arm的汇编器、链接器等。arm-elf-ld,-ar,-as...

2、下载gcc源代码用本地gcc编译出针对arm的编译器,此步骤需要用到binutils的输出ld,ar,as等。

3、编译C运行时库

 

具体上面3个步骤如何实现在网上搜一下就知道啦~不罗嗦了 这里就只讲下概念由于能力有限,如有错误请不吝指正,谢谢~

附图:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值