全手工制作arm-linux交叉编译工具链
R}lsnX< (Gcc 4.2.1 + Glibc 2.6.1 + Linux 2.6.22.6)《一》
}; f#^gz' 作者:Garfield Trump
pek%08VSEU 仅仅是本人在
学习嵌入式系统时的体会、看法,难免有理解错误,乐意接受阅读本文的各方人士指
;PjQt=4K 出错误。
\ gLHi~ 联系方式:
Garfield_Trump@yahoo.com :_t}QP" 本文
原理部分主要参考并引用下面网址的文章:
S(uf(q|{ http://www.decell.org/article.asp?id=53 ;_^fk&+ 但因为此文制作的版本太旧,本人没有使用,但经过验证是可以成功制作的。
yQ^($#Yk 本文制作使用的
软件版本主要参照以下网址:
z.Y$7bf) http://cross-lfs.org/view/clfs-sysroot/arm/ #Sa27$&.> 但此网址的制作过程有错,Garfield Trump 在本文予以纠正。
aj?a^}X 《一》环境配置:
/)dFK~ 工作站:基于x86体系的个人计算机或其他同类的计算机系统。
f-5:wM& 目标平台:基于
ARM v4I 内核体系结构的SoC系统,本文使用的目标系统是三星公司的S3C2410系列
b^p"|L 。
[o.B 软件环境:
x-?{E 工作站:
CMn{LQcC 目标平台:无相关要求。
"dI; 《二》概述
YhY:~ 当我们需要从
源代码编译出一个能运行在ARM 架构上的程序的时候,我们可以有两种方法。第一种
>2< 8kBF_ 是像我们平常一样,使用相同架构机器上的编译器,编译出运行在同一架构上的程序。在嵌入式系
:%sXO 统领域,这是较难实现的。嵌入式系统的在设计的时候由于考虑到功耗,体积等要求,性能往往较
t
0-(U\ 弱。在编译一些比较大规模的程序时候,嵌入式系统在编译上耗费的时间,是我们无法忍受的。因
9:e YU
= 此,我们需要使用交叉编译
技术。
jK' N((Hz 交叉编译技术,是一种在一个异构平台上编译出目标平台程序的一种技术。理论上来说,交叉工具
XK: 9r{r{ 链可以用在任何两种异构的系统中,例如,我们可以构建出PowerPC-ARM工具链,Sun Sparc-x86工
e'=MQ,EWd 具链等等。目前交叉工具链一般用于目标平台计算能力较弱,需要其他计算能力较强的平台帮助产
rtL}W__ 生可运行软件的场合。在基于ARM的嵌入式系统开发中,我们一般会使用x86架构的计算机系统作
TOoQZTI 为工作站,故最为
常用的是x86-ARM交叉工具链。 目前市场上存在着各种各样不用的
bd<m%OM"" x86-ARM交叉工具链,有ARM公司自家在RVDS开发工具中整合的armcc,有Microsoft
9Ffp2NW`; 在Platform Builder中的armv4I 编译器等。一般来说,这些由商业公司提供的工具链,都不会附有工
C#H:-Q& 具链相关的源代码和制作方法,灵活性不足,并且它们一般都与整套开发系统捆绑销售使用,成本
@"o@}9=d 较高。为了更好的理解这种技术和降低成本,获得更好的灵活性,市场上有不少的公司使用国际开
x3u4v~ "- 源组织GNU开发的工具链作为他们产品开发的工具。本文下面的章节就为大家展示一个完整的
'&sE=. GNU工具链构建过程。其中可能涉及到一些GNU Linux系统的基本操作知识,如果大家对此认识不
SL,p36N 深,请自行查阅相关
资料。
|U_]vMq 《三》工具链原理及构建方法
V=lfl1Ev0J 3.1原理:
5*0y7K/D 每一个软件,在编译的过程中,都要经过一系列的处理,才能从源代码变成可执行的目标代码。这
a\%xB >LX 一系列处理包括:预编译,高级语言编译,汇编,连接及重定位。这一套流程里面用到的每个工具
IXb}AxBf 和相关的库组成的集合,就称为工具链(tool chain)。以GNU的开发工具GCC为例,它就包括了预
)x]3Zq 编译器cpp,c编译器gcc,汇编器as,和连接器ld等。在GNU自己对工具链定义中,还加进了一套额
8Th` ]tI 外的用于处理二进制包的工具包binutils,整个工具链应该是GCC+binutils+Glibc,不过大家后面将会
tqy@iEz+ 看到binutils其实与Glibc无关,它是可以被独立安装的,所以GNU工具链也可以狭义地被理解为
{O+Kw<d GCC+Glibc。
J7v|vjI 一般的情况下,工具链运行的环境和它产生的目标代码的环境是一致的。例如我们在VC中编译一个
'(dz"PL. 程序,工具链运行在x86平台,产生的也是运行在x86平台上的代码。但实际上,工具链产生的目标
+n7?S~R$ 代码的运行平台是可以跟工具链运行的环境不一致的。这种产生与运行环境不一致的目标代码的工
|,aG%MTL 具链,称为交叉工具链(cross-compiler tool chain),使用这种工具链的编译过程对应地被称为交叉编
5bA)j!#)|X 译(cross-compile)。在GNU中,一般在普通工具链名称的前面加上特定的前缀,以表示是什么类型的
JkGnKm9G 工具链。例如x86-arm的工具链,预编译器是arm-linux-cpp,c编译器arm-linux-gcc等。
!o>H1#2l 要构建出一个交叉工具链,需要解决三个问题。一是这个工具链必须是可以运行在原工作站平台上
lw :`M2P, 的。二是我们需要更换一个与目标平台对应的汇编器,使得工具链能产生对应的目标代码,三是要
NNF>Xa`9, 更换一套与目标平台对应的二进制库,使得工具链在连接时能找到正确的二进制库。
0v]?6wX 3.2构建方法
z.6$W^ 3.2.1建立binutils
|Xw/E)jA 首先我们建一个目录,作为存放工具链的地方。因为binutils和Glibc头文件的独立性,我们先把他们
vBsP+K 放到这个目录里面。如示意图1所示
%J8|zKT5t 示意图1 (新加入内容以下划线标记)
<&!v1yR 3.2.2 建立GCC Stage1
p2N:;lXM 然后我们使用工作站平台的工具链,编译出一条交叉工具链,通过指定工具链的类型,我们可以控
r)T:7zy 制该工具链汇编器的输出类型。但此时该工具链指向库依然是工作站平台的二进制库。此阶段称为
>+mD$:L GCC Stage1。如示意图2所示
XTd3|Pm 示意图2(新加入内容以下划线标记)
*#TYqCc+g 3.2.3 建立构建一个目标平台的二进制库
.)+hH y 接下来我们利用刚刚建立的GCC构建一个目标平台的二进制库。由于二进制库都是自包含的,所以
1pCieTz!PN 我们无需担心这个二进制库中会调用工作站平台的库进而产生依赖问题。见示意图3
IQ!\w- 示意图3(新加入内容以下划线标记)
ZbT/$\0(6 3.2.4 建立GCC Stage2
!I\!;b 最后我们使用工作站平台的工具链重新编译一次GCC,使得GCC指向新编译出来的库,此阶段称为
Nk[2nyeO> GCC Stage2。见示意图4
Pub0IIs 示意图4(新加入内容以下划线标记)
h!#:$|Q 全手工制作arm-linux交叉编译工具链
<jS~ WI@ (Gcc 4.2.1 + Glibc 2.6.1 + Linux 2.6.22.6)《二》
xP=/N!,# 作者:Garfield Trump
vfNAs>X g" 《四》具体实现:
fGv#s
X http://cross-lfs.org/view/clfs-sysroot/arm/index.html |8bq>01~ 在此部分的制作过程主要参考以上网站完成,但其中制作过程有错,在本文中Garfield Trump予以了
Lw'9 纠正。读者可以事后参看一下。我会在以下篇幅中指出与该网站的不同之处,并说明错在什么地方
!;Jmg 。
j&