原文链接与:实验室的机器配置太低,速度太慢实在是受不了。说是已经升级了,内存从128M升级到了256M。Mygod!这年头还能到什么地方找那么多128的内存条去阿?哇嘎嘎。真是服了。。。哈哈打开一个pdf文件要等老半天。基本上没有办法工作。于是想在自己的笔记本上做一个交叉编译环境。我的机器配置也不高,但是相对于实验室的机器来说已经相当不错了。我的机器是单操作系统:只有Ubuntu8.0.4。感觉和windowsXP差不多。XP下有的东西,ubuntu下基本上也有。ps:昨天是我的生日。昨天上午有课,一下午还有今天上午就是在交叉编译的过程中度过的。感觉整个过程挺考验耐心的。下面进入正题。待续。。。最近两天内补充完整。*************************************************************************************在进行嵌入式在进行嵌入式开发之前,首先要建立一个交叉编译环境,这是一套编译器、连接器和libc库等组成的开发环境。本文结合自己做嵌入式交叉编译开发工作的经验,同时结合自己的体会,做了一个介绍随着消费类电子产品的大量开发和应用和Linux操作系统的不断健壮和强大,嵌入式系统越来越多的进入人们的生活之中,应用范围越来越广。在裁减和定制Linux,运用于你的嵌入式系统之前,由于一般嵌入式开发系统存储大小有限,通常你都要在你的强大的pc机上建立一个用于目标机的交叉编译环境。这是一个由编译器、连接器和解释器组成的综合开发环境。交叉编译工具主要由binutils、gcc和glibc几个部分组成。有时出于减小libc库大小的考虑,你也可以用别的c库来代替glibc,例如uClibc、dietlibc和newlib。建立一个交叉编译工具链是一个相当复杂的过程,如果你不想自己经历复杂的编译过程,网上有一些编译好的可用的交叉编译工具链可以下载。交叉编译介绍•交叉编译就是在一个平台上生成另一个平台上的可执行代码。•这里说的平台分别指的是主机平台Host和目标平台Target。•就我们在ARM平台上移植Linux来说,Host是一台一般的PC机,它通过串口或网络接口与Target通信;Target是arm-linux平台(这里说的arm指的是平台所使用的CPU是ARM9处理器,linux指的是运行的操作系统是Linux)。•我们在Host上开发程序,并在这个平台上运行交叉编译器CrossComplier,编译我们的程序,而由CrossComplier生成的程序将在Target上运行。•目前常用的交叉开发环境主要有开放和商业两种类型。–开放的交叉开发环境的典型代表是GNU工具链,目前已能够支持x86、ARM、PowerPC等多种处理器。–商业的交叉开发环境主要有MetrowerksCodeWarrior、ARMSoftwareDevelopmentToolkit等。常用在ARM平台的GNUToolchain:•arm-linux-gcc:交叉编译linux内核•arm-elf-gcc:主要交叉编译uclinux内核•arm-uclinux-gcc:交叉编译uclinux内核主要下载网址(网址)•下载下来之后的几种安装方式:•sh脚本方式安装(.sh)–sharm-elf-tools-20030314.sh•tar解压方式安装(.tar.gz)–tarzxvfarm-linux-gcc-2.95.3.tar.gz•rpm安装包方式安装(.rpm)–rpm–ivharm-linux-gcc-2.95.3-3.i386.rpm–rpm–ivharm-linux-binutils-2.12.1-1.i386.rpm–rpm–ivharm-linux-glibc-2.2.5-1.i386.rpm•安装目录:/usr/local/bin/arm-elf-xxx/usr/local/arm-linux/bin/arm-linux-xxx/usr/local/arm-uclinux-tool/bin/arm-uclinux-xxx为了在命令行中能够寻找到交叉编译器,我们需要把他所在的路径加入到PATH环境变量中(例:/usr/local/arm/bin:$PATH)。交叉编译环境的组成:•binutils工具包:包括连接器、汇编器以及其他用于目标文件和档案的工具,如as汇编器,ld连接器等。•gcc工具包:工具链的主角,包括c编译器gcc、c++编译器g++等。•glibc库:提供系统调用的基本函数的C库,比如,printf、open等。•gdb调试工具:运行在target上的调试程序,通过串口和TCP/IP和主机连接,进行远距离调试。需要交叉编译的原因:•首先,在项目的起始阶段,目标平台尚未建立,因此需要做交叉编译,以生成我们所需要的Bootloader以及kernel(因为Bootloader和kernel的源码需要经过交叉编译后才可以在目标平台上运行);•其次,当目标平台能启动之后,由于目标平台上资源的限制,当我们编译大型程序时,依然可能需要用到交叉编译。因此,建立交叉编译环境是进行嵌入式软件开发的第一步。下面我们将以建立针对arm的交叉编译开发环境为例来说明整个交叉编译器DIY的过程,其他的体系结构与这个相类似,只要作一些对应的改动。我的开发环境是,宿主机i386-ubuntu-8.04,目标机arm。因为Linux内核版本多,不同的版本存在不同的bug,加之众多版本的工具链也存在不同的bug,这些bug针对不同的硬件(比如CPU类型等),需要多方测试,寻找合适的补丁程序。我是从网上看到大家都按如下的这个过程进行(我也是这么做的):1.下载源文件、补丁和建立编译的目录2.建立内核头文件3.建立二进制工具(binutils)4.建立初始编译器(bootstrapgcc)5.建立c库(glibc)6.建立全套编译器(fullgcc)(一)下载源文件、补丁和建立编译的目录1.选定软件版本号选择软件版本号时,先看看glibc源代码中的INSTALL文件。那里列举了该版本的glibc编译时所需的binutils和gcc的版本号。例如在glibc-2.2.3/INSTALL文件中推荐gcc用2.95以上,binutils用2.10.1以上版本。网上有推荐的如下比较稳定的而且出错比较少的几个版本组合如下,以下是已选定的构建交叉编译环境的工具链版本:–BINUTILS_VERSION=2.16–GCC_VERSION=3.4.3–GCCCORE_VERSION=3.4.3–LINUX_VERSION=2.4.21–GLIBC_VERSION=2.3.5–GLIBCTHREADS_VERSION=2.3.5我选的各个软件的版本也大致如此,其具体如下:binutils-2.10.1()gcc-2.95.3()glibc-2.2.3()glibc-linuxthreads-2.2.3()linux-2.4.21-rmk2()linux-2.4.21.tar.gz()gccpatch下载:如果你选的glibc的版本号低于2.2,你还要下载一个叫glibc-crypt的文件,例如glibc-crypt-2.1.tar.gz。Linux内核你可以从或它的镜像下载。Binutils、gcc和glibc你可以从FSF的FTP站点或它的镜像去下载。在编译glibc时,要用到Linux内核中的include目录的内核头文件。如果你发现有变量没有定义而导致编译失败,你就改变你的内核版本号。例如我开始用linux-2.4.25+vrs2,编译glibc-2.2.3时报BUS_ISA没定义,后来发现在2.4.23开始它的名字被改为CTL_BUS_ISA。如果你没有完全的把握保证你改的内核改完全了,就不要动内核,而是把你的Linux内核的版本号降低或升高,来适应glibc。Gcc的版本号,推荐用gcc-2.95以上的。太老的版本编译可能会出问题。Gcc-2.95.3是一个比较稳定的版本,也是内核开发人员推荐用的一个gcc版本。如果你发现无法编译过去,有可能是你选用的软件中有的加入了一些新的特性而其他所选软件不支持的原因,就相应降低该软件的版本号。例如我开始用gcc-3.3.2,发现编译不过,报as、ld等版本太老,我就把gcc降为2.95.3。太新的版本大多没经过大量的测试,建议不要选用。(二)建立工作目录首先,我们建立几个用来工作的目录:在你的用户目录,我用的是用户tang,因此用户目录为/home/tang,先建立一个项目目录cross。tang@tang-laptop:~$pwd/home/tangtang@tang-laptop:~$mkdircross再在这个项目目录cross下建立三个目录build-tools、kernel和tools。build-tools-用来存放你下载的binutils、gcc和glibc的源代码和用来编译这些源代码的目录。kernel-用来存放你的内核源代码和内核补丁。tools-用来存放编译好的交叉编译工具和库文件。tang@tang-laptop:~$cdcrosstang@tang-laptop:~/cross$mkdirbuild-toolskerneltools执行完后目录结构如下:tang@tang-laptop:~/cross$ls./build-toolskerneltools3.输出和环境变量我们输出如下的环境变量方便我们编译。tang@tang-laptop:~/cross$exportPRJROOT=home/tang/crosstang@tang-laptop:~/cross$exportTARGET=arm-linuxtang@tang-laptop:~/cross$exportPREFIX=$PRJROOT/toolstang@tang-laptop:~/cross$exportTARGET_PREFIX=$PREFIX/$TARGETtang@tang-laptop:~/cross$exportPATH=$PREFIX/bin:$PATH如果你不惯用环境变量的,你可以直接用绝对或相对路径。我如果不用环境变量,一般都用绝对路径,相对路径有时会失败。环境变量也可以定义在.bashrc文件中,这样当你logout或换了控制台时,就不用老是export这些变量了。体系结构和你的TAEGET变量的对应如下表你可以在通过glibc下的config.sub脚本来知道,你的TARGET变量是否被支持,例如:tang@tang-laptop:../glibc-2.2.3/scripts$./config.subarm-linuxarm-unknown-linux-gnu在我的环境中,config.sub在glibc-2.2.3/scripts目录下。网上还有一些HOWTO可以参考,ARM体系结构的《TheGNUToolchainforARMTarg