一、交叉编译介绍

1、交叉编译器

在 X86 架构 Linux 系统下进行 C 程序开发时, 我们使用系统的 gcc 编译器进行代码的编译, 编译生成的可执行程序直接在 X86 架构下的 PC 下运行的,这个过程叫做 本地编译 (Native Compile) 。 而如果该C程序想要编译出来后放到ARM处理器架构的系统上运行, 则需要在 X86 架构Linux系统下使用支持 ARM 的编译器编译, 这个编译器我们通常称为 交叉编译器 (Cross Compiler)。

而在一种平台上编译出能在另外一种体系结构完全不同处理器上运行程序的编译过程,叫做 交叉编译(Cross Compile)。比如在PC平台(X86 CPU)上编译出能运行在以ARM为内核的CPU平台上的程序,编译得到的程序在X86 CPU平台上是不能运行的,必须放到ARM CPU平台上才能运行,虽然两个平台用的都是Linux系统。
交叉编译示意
交叉编译工具链是一个由编译器、连接器和解释器组成的综合开发环境,交叉编译工具链主要由binutils、gcc和glibc三个部分组成。有时出于减小 libc 库大小的考虑,也可以用别的 c 库来代替 glibc, 例如 uClibc 或 newlib。

几乎所有的ARM开发板开发都选择交叉编译,因为这些开发板生产出来后并没有系统,这 时需要在PC上使用交叉编译器交叉编译操作系统源码,为它构建一个完整的 Linux 系统。

另外,由于CPU处理能力、外存和内存存储空间的大小限制,它们不足以能够运行 gcc 编译环境,所以嵌入式开发绝大部分的过程都是交叉编译。

2、常用交叉编译器

(1)Codesourcery 交叉编译器

Codesourcery一直是在做 ARM 目标 GCC 的开发和优化,它直接提供 Windows和Linux下的二进制版本交叉编译器,不用下载源码包一步一步自己编译,非常方便。它的 ARM GCC 早期在市场上非常优秀,很多公司在作嵌入式产品开发时,都会直接下载使用该公司提供的交叉编译器。

Codesourcery 推出的产品叫 Sourcery G++ Lite Edition, 其中基于 command-line 的编译器是免费的, 在官网上可以下载, 而其中包含的 IDE 和 debug 工具是收费的, 当然也有30天试用版本的。后来CodeSourcery 被明导国际(Mentor Graphics)收购, 现在则被西门子(Siemens) 收购了。(注:现在好像下载不了)

(2)Linaro交叉编译器

除了CodeSourcery外,还有一个组织也提供ARM Toolchain,它就是Linaro。
Linaro是在2010年台北国际计算机展(COMPUTEX)期间,ARM、Freescale、Samsung ,ST-Ericsson、德州仪器(TI)与IBM等6家大厂,宣布合资成立的非赢利Linux基础架构软件研发商。

Linaro目标在投入新资源和集成业界的努力,改进与优化在ARM-based架构上运行的开放原始码软件及 开发工具,将过去必须由系统单芯片(SoC)业者,各自将本身产品与Linux操作系统集成与开发的重复投资,透过这间合资公司推出开放原始码的底层软件工具,解决ARM生态系中,重复投资造成的资源浪费。

二、交叉编译器说明

1、命名规则

交叉编译工具链的命名规则为:arch [-vendor] [-os] [-(gnu)eabi]

  • arch – 体系架构,如 ARM,MIPS
  • vendor – 工具链提供商:none,linaro
  • os – 目标操作系统:linux, none (bare metal)
  • eabi – 嵌入式应用二进制接口(Embedded Application Binary Interface):eabi, gnueabi, gnueabihf

根据对操作系统的支持与否,ARM GCC 可分为支持和不支持操作系统,如

  • arm-none-eabi:这个是没有操作系统的,自然不可能支持那些跟操作系统关系密切的函数,比如 fork(2)。他使用的是 newlib 这个专用于嵌入式系统的 C 库。
  • arm-none-linux-eabi:用于 Linux 的,使用 Glibc

2、ABI和EABI

(1)ABI:二进制应用程序接口

ABI:二进制应用程序接口 (Application Binary Interface (ABI) for the ARM Architecture)
在计算机中,应用二进制接口描述了应用程序(或者其他类型)和操作系统之间或其他应用程序的低级接口。ABI涵盖了各种细节,如:

  • 数据类型的大小、布局和对齐;
  • 调用约定(控制着函数的参数如何传送以及如何接受返回值),例如,是所有的参数都通过栈传递,还是部分参数通过寄存器传递;哪个寄存器用于哪个函数参数;通过栈传递的第一个函数参数是最先push到栈上还是最后;
  • 系统调用的编码和一个应用如何向操作系统进行系统调用;
  • 以及在一个完整的操作系统ABI中,目标文件的二进制格式、程序库等等。

一个完整的ABI,像Intel二进制兼容标准 (iBCS) ,允许支持它的操作系统上的程序不经修改在其他支持此ABI的操作体统上运行。

ABI不同于应用程序接口(API),API定义了源代码和库之间的接口,因此同样的代码可以在支持这个API的任何系统中编译,ABI允许编译好的目标代码在使用兼容ABI的系统中无需改动就能运行。

(2)EABI:嵌入式 ABI

EABI: 嵌入式ABI。嵌入式应用二进制接口指定了文件格式、数据类型、寄存器使用、堆积组织优化和在一个嵌入式软件中的参数的标准约定。

  • 开发者使用自己的汇编语言也可以使用EABI作为与兼容的编译器生成的汇编语言的接口。
  • 支持EABI的编译器创建的目标文件可以和使用类似编译器产生的代码兼容,这样允许开发者链接一个由不同编译器产生的库。

EABI与关于通用计算机的ABI的主要区别是应用程序代码中允许使用特权指令,不需要动态链接(有时是禁止的),和更紧凑的堆栈帧组织用来节省内存。广泛使用EABI的有Power PC和ARM.

3、各交叉编译器介绍与比较

(1)arm-none-eabi-gcc

(ARM architecture,no vendor,not target an operating system,complies with the ARM EABI)
用于编译 ARM 架构的裸机系统(包括 ARM Linux 的 boot、kernel,不适用编译 Linux 用 Application),一般适合 ARM7、Cortex-M 和 Cortex-R 内核的芯片使用,所以不支持那些跟操作系统关系密切的函数,比如 fork(2),他使用的是 newlib 这个专用于嵌入式系统的 C 库。

(2)arm-none-linux-gnueabi-gcc

(ARM architecture, no vendor, creates binaries that run on the Linux operating system, and uses the GNU EABI)
主要用于基于 ARM 架构的 Linux 系统,可用于编译 ARM 架构的 u-boot、Linux 内核、linux 应用等。arm-none-linux-gnueabi 基于 GCC,使用 Glibc 库,经过 Codesourcery 公司优化过推出的编译器。
arm-none-linux-gnueabi-xxx 交叉编译工具的浮点运算非常优秀。一般 ARM9、ARM11、Cortex-A 内核,带有 Linux 操作系统的会用到。

Arm-none-linux-gnueabi 和 arm-linux-gnueabi 是一回事,可能只是发行厂家不同。

(3)arm-linux-gnueabi-gcc 和 arm-linux-gnueabihf-gcc

arm-linux-gnueabi-gcc和 arm-linux-gnueabihf-gcc是由 Linaro 公司基于GCC推出的的ARM交叉编译工具。可用于交叉编译ARM(32位)系统中所有环节的代码,包括裸机程序、u-boot、Linux kernel、filesystem和App应用程序。

两个交叉编译器分别适用于 armel 和 armhf 两个不同的架构,armel 和 armhf 这两种架构在对待浮点运算采取了不同的策略(有 fpu 的 arm 才能支持这两种浮点运算策略)。

其实这两个交叉编译器只不过是 gcc 的选项 -mfloat-abi 的默认值不同。gcc 的选项 -mfloat-abi 有三种值soft、softfp、hard(其中后两者都要求 arm 里有 fpu 浮点运算单元,soft 与后两者是兼容的,但 softfp 和 hard 两种模式互不兼容):
soft: 不用 fpu 进行浮点计算,即使有 fpu 浮点运算单元也不用,而是使用软件模式。
softfp: armel 架构(对应的编译器为 arm-linux-gnueabi-gcc )采用的默认值,用 fpu 计算,但是传参数用普通寄存器传,这样中断的时候,只需要保存普通寄存器,中断负荷小,但是参数需要转换成浮点的再计算。
hard: armhf 架构(对应的编译器 arm-linux-gnueabihf-gcc)采用的默认值,用 fpu 计算,传参数也用 fpu 中的浮点寄存器传,省去了转换,性能最好,但是中断负荷高。

把以下测试使用的 C 文件内容保存成 mfloat.c:

  1. #include <stdio.h>
  2. int main(void)
  3. {
  4. double a,b,c;
  5. a = 23.543;
  6. b = 323.234;
  7. c = b/a;
  8. printf(“the 13/2 = %f\n”, c);
  9. printf(“hello world !\n”);
  10. return 0;
  11. }
  1. #使用arm-linux-gnueabihf-gcc编译,使用“-v”选项以获取更详细的信息:
  2. # arm-linux-gnueabihf-gcc -v mfloat.c
  3. COLLECT_GCC_OPTIONS=’-v ‘-march=armv7-a ‘-mfloat-abi=hard ‘-mfpu=vfpv3-d16 ‘-mthumb
  4. -mfloat-abi=hard,可看出使用hard硬件浮点模式。
  5. #使用arm-linux-gnueabi-gcc编译:
  6. # arm-linux-gnueabi-gcc -v mfloat.c
  7. COLLECT_GCC_OPTIONS=’-v ‘-march=armv7-a ‘-mfloat-abi=softfp ‘-mfpu=vfpv3-d16 ‘-mthumb

(4)arm-eabi-gcc

Android ARM 编译器。

(5)armcc

ARM 公司推出的编译工具,功能和 arm-none-eabi 类似,可以编译裸机程序(u-boot、kernel),但是不能编译 Linux 应用程序。armcc 一般和 ARM 开发工具一起,Keil MDK、ADS、RVDS 和 DS-5 中的编译器都是 armcc,所以 armcc 编译器都是收费的。

(6)arm-none-uclinuxeabi-gcc 和 arm-none-symbianelf-gcc

arm-none-uclinuxeabi 用于uCLinux,使用 Glibc。
arm-none-symbianelf 用于symbian

比较 ARMCC IAR GCC for ARM LLVM(clang)
命令行工具 随 IDE 发布,也独立提供 仅随其 IDE 发布,不独立提供 独立提供 只有命令行工具
开发商 ARM IAR ARM、Linaro、Mentor LLVM
支持的平台 Windows、Linux Windows Windows、Linux、Mac(部分) Windows、Linux、Mac
配套 IDE Keil MDK、ARM Development Studio 5、ADS IAR EMBEDDED WORKBENCH FOR ARM 除以上两者外的其他支持 ARM 的 IDE,例如:eclipse、Visual Studio 除以上两者外的其他支持 ARM 的 IDE,例如:eclipse、Visual Studio

三、各类交叉编译器安装

1、arm-none-linux-gnueabi-gcc安装

Linux Desktop系统配置
arm-none-linux-gnueabi-gcc是 Codesourcery 公司(目前已经被 Mentor 收购)基于 GCC 推出的的 ARM交叉编译工具。可用于交叉编译 ARM 系统中所有环节的代码,包括裸机程序、u-boot、Linux kernel、filesystem 和 App 应用程序。使用时,按照主机平台,可以下载以下任一版本中的一个,结果是一样的:

  • Linux 解压版:在 Linux 主机(如 Ubuntu、RedHat 等)直接解压即可使用。推荐方式
  • Linux 安装版:在 Linux 主机下执行后按照提示安装后使用。
  • Windows 解压版:在 Windows 系统下解压后使用,但是需要 MingW32。
  • Windows 安装版:在 Windows 系统下安装后使用。
  • 源码版:交叉编译器源代码,一般很少用到。

为方便国内用户下载使用,我们从 Codesourcery(Mentor)官网下载了所有版本的 arm-none-linux-gnueabi-gcc 编译器,并放到国内云盘上提供下载。因为版本很多,可能难以选择,但是我们建议您使用最新版本,即有最新~标志的下载项。

(1)Linux 解压版

gnu-csl-arm-2005Q1B-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2006q1-3-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2006q1-6-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2006q3-26-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2007q1-10-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2007q1-21-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2008q1-126-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2008q3-41-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2008q3-72-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2009q1-176-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2009q1-203-arm-none-linux-gnueabi-i686-pc-linux-gnu.bz2 —— 下载
arm-2009q3-67-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2010.09-50-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2010q1-202-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2011.03-41-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2012.09-64-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2013.05-24-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2013.11-33-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 —— 下载
arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 最新~ 推荐!—— 下载

(2)Linux 安装版

arm-2006q3-26-arm-none-linux-gnueabi.bin —— 下载
arm-2007q1-10-arm-none-linux-gnueabi.bin —— 下载
arm-2007q1-21-arm-none-linux-gnueabi.bin —— 下载
arm-2007q3-51-arm-none-linux-gnueabi.bin —— 下载
arm-2008q1-126-arm-none-linux-gnueabi.bin —— 下载
arm-2008q3-41-arm-none-linux-gnueabi.bin —— 下载
arm-2008q3-72-arm-none-linux-gnueabi.bin —— 下载
arm-2009q1-176-arm-none-linux-gnueabi.bin —— 下载
arm-2009q1-203-arm-none-linux-gnueabi.bin —— 下载
arm-2009q3-67-arm-none-linux-gnueabi.bin —— 下载
arm-2010.09-50-arm-none-linux-gnueabi.bin —— 下载
arm-2010q1-202-arm-none-linux-gnueabi.bin —— 下载
arm-2011.03-41-arm-none-linux-gnueabi.bin —— 下载
arm-2011.09-70-arm-none-linux-gnueabi.bin —— 下载
arm-2012.03-57-arm-none-linux-gnueabi.bin —— 下载
arm-2012.09-64-arm-none-linux-gnueabi.bin —— 下载
arm-2013.05-24-arm-none-linux-gnueabi.bin —— 下载
arm-2013.11-33-arm-none-linux-gnueabi.bin —— 下载
arm-2014.05-29-arm-none-linux-gnueabi.bin —— 最新~ 下载

(3)Windows Mingw32 版

gnu-csl-arm-2005Q1B-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2006q3-26-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2007q1-10-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2007q1-21-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2007q3-51-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2008q1-126-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2008q3-41-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2008q3-72-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2009q1-176-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2009q1-203-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2009q3-67-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2010.09-50-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2010q1-202-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2011.03-41-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2011.09-70-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2012.03-57-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2012.09-64-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2013.05-24-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2013.11-33-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 下载
arm-2014.05-29-arm-none-linux-gnueabi-i686-mingw32.tar.bz2 —— 最新~ 下载

(4)Windows 安装版

gnu-csl-arm-2005Q1B-arm-none-linux-gnueabi.exe —— 下载
arm-2006q1-3-arm-none-linux-gnueabi.exe —— 下载
arm-2006q1-6-arm-none-linux-gnueabi.exe —— 下载
arm-2006q3-26-arm-none-linux-gnueabi.exe —— 下载
arm-2007q1-10-arm-none-linux-gnueabi.exe —— 下载
arm-2007q1-21-arm-none-linux-gnueabi.exe —— 下载
arm-2007q3-51-arm-none-linux-gnueabi.exe —— 下载
arm-2008q1-126-arm-none-linux-gnueabi.exe —— 下载
arm-2008q3-41-arm-none-linux-gnueabi.exe —— 下载
arm-2008q3-72-arm-none-linux-gnueabi.exe —— 下载
arm-2009q1-176-arm-none-linux-gnueabi.exe —— 下载
arm-2009q1-203-arm-none-linux-gnueabi.exe —— 下载
arm-2009q3-67-arm-none-linux-gnueabi.exe —— 下载
arm-2010.09-50-arm-none-linux-gnueabi.exe —— 下载
arm-2010q1-202-arm-none-linux-gnueabi.exe —— 下载
arm-2011.03-41-arm-none-linux-gnueabi.exe —— 下载
arm-2011.09-70-arm-none-linux-gnueabi.exe —— 下载
arm-2012.03-57-arm-none-linux-gnueabi.exe —— 下载
arm-2012.09-64-arm-none-linux-gnueabi.exe —— 下载
arm-2013.05-24-arm-none-linux-gnueabi.exe —— 下载
arm-2013.11-33-arm-none-linux-gnueabi.exe —— 下载
arm-2014.05-29-arm-none-linux-gnueabi.exe —— 最新~ 下载

(5)源码

gnu-csl-arm-2005Q1B-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2006q1-3-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2006q1-6-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2006q3-26-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2007q1-10-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2007q1-21-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2007q3-51-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2008q1-126-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2008q3-41-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2008q3-72-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2009q1-176-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2009q1-203-arm-none-linux-gnueabi.src.tar.bz2.bz2 —— 下载
arm-2009q3-67-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2010.09-50-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2010q1-202-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2011.03-41-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2011.09-70-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2012.03-57-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2012.09-64-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2013.05-24-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2013.11-33-arm-none-linux-gnueabi.src.tar.bz2 —— 下载
arm-2014.05-29-arm-none-linux-gnueabi.src.tar.bz2 —— 最新~ 下载

2、arm-linux-gnueabi-gcc 安装

arm-linux-gnueabi-gcc是由 Linaro 公司基于GCC推出的的ARM交叉编译工具(待考证)。可用于交叉编译ARM(32位)系统中所有环节的代码,包括裸机程序、u-boot、Linux kernel、filesystem和App应用程序。

ubuntu可以直接通过安装命令安装

参考资料