ARM交叉编译⼯具链分类说明
为什么要⽤交叉编译器?
交叉编译通俗地讲就是在⼀种平台上编译出能运⾏在体系结构不同的另⼀种平台上的程序,⽐如在PC平台(X86 CPU)上编译出能运⾏在以ARM为内核的CPU平台上的程序,编译得到的程序在X86 CPU平台上是不能运⾏的,必须放到ARM CPU平台上才能运⾏,虽然两个平台⽤的都是Linux系统。
交叉编译⼯具链是⼀个由编译器、连接器和解释器组成的综合开发环境,交叉编译⼯具链主要由binutils、gcc和glibc三个部分组成。有时出于减⼩ libc 库⼤⼩的考虑,也可以⽤别的 c 库来代替 glibc,例如 uClibc、dietlibc 和 newlib。建⽴交叉编译⼯具链是⼀个相当复杂的过程,如果不想⾃⼰经历复杂繁琐的编译过程,⽹上有⼀些编译好的可⽤的交叉编译⼯具链可以下载,但就以学习为⽬的来说读者有必要学习⾃⼰制作⼀个交叉编译⼯具链(⽬前来看,对于初学者没有太⼤必要⾃⼰交叉编译⼀个⼯具链)。
分类和说明
从授权上,分为免费授权版和付费授权版。
免费版⽬前有三⼤主流⼯具商提供,第⼀是GNU(提供源码,⾃⾏编译制作),第⼆是 Codesourcery,
第三是Linora。
收费版有ARM原⼚提供的armcc、IAR提供的编译器等等,因为这些价格都⽐较昂贵,不适合学习⽤户使⽤,所以不做讲述。
arm-none-linux-gnueabi-gcc:是 Codesourcery 公司(⽬前已经被Mentor收购)基于GCC推出的的ARM交叉编译⼯具。可⽤于交叉编译ARM(32位)系统中所有环节的代码,包括裸机程序、u-boot、Linux kernel、filesystem和App应⽤程序。
arm-linux-gnueabihf-gcc:是由 Linaro 公司基于GCC推出的的ARM交叉编译⼯具。可⽤于交叉编译ARM(32位)系统中所有环节的代码,包括裸机程序、u-boot、Linux kernel、filesystem和App应⽤程序。
aarch64-linux-gnu-gcc:是由 Linaro 公司基于GCC推出的的ARM交叉编译⼯具。可⽤于交叉编译ARMv8 64位⽬标中的裸机程序、u-boot、Linux kernel、filesystem和App应⽤程序。
arm-none-elf-gcc:是 Codesourcery 公司(⽬前已经被Mentor收购)基于GCC推出的的ARM交叉编译⼯具。可⽤于交叉编译ARM MCU(32位)芯⽚,如ARM7、ARM9、Cortex-M/R芯⽚程序。
arm-none-eabi-gcc:是 GNU 推出的的ARM交叉编译⼯具。可⽤于交叉编译ARM MCU(32位)芯⽚,
如ARM7、ARM9、Cortex-M/R芯⽚程序。
交叉编译器下载
arm-none-linux-gnueabi-gcc下载:
arm-linux-gnueabihf-gcc下载:
aarch64-linux-gnu-gcc下载:
arm-none-elf-gcc下载:
arm-none-eabi-gcc下载:
命名规则
交叉编译⼯具链的命名规则为:arch [-vendor] [-os] [-(gnu)eabi]
arch - 体系架构,如ARM,MIPS
vendor - ⼯具链提供商
x86架构和arm架构区别
os - ⽬标操作系统
eabi - 嵌⼊式应⽤⼆进制接⼝(Embedded Application Binary Interface)
根据对操作系统的⽀持与否,ARM GCC可分为⽀持和不⽀持操作系统,如
arm-none-eabi:这个是没有操作系统的,⾃然不可能⽀持那些跟操作系统关系密切的函数,⽐如fork(2)。他使⽤的是newlib这个专⽤于嵌⼊式系统的C库。
arm-none-linux-eabi:⽤于Linux的,使⽤Glibc
实例
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 操作系统的会⽤到。
3、arm-eabi-gcc
Android ARM 编译器。
4、armcc
ARM 公司推出的编译⼯具,功能和 arm-none-eabi 类似,可以编译裸机程序(u-boot、kernel),但是不能编译 Linux 应⽤程序。armcc⼀般和ARM开发⼯具⼀起,Keil MDK、ADS、RVDS和DS-5中的编译器都是armcc,所以 armcc 编译器都是收费的(爱国版除外,呵呵~~)。
5、arm-none-uclinuxeabi-gcc 和 arm-none-symbianelf-gcc
arm-none-uclinuxeabi ⽤于uCLinux,使⽤Glibc。
arm-none-symbianelf ⽤于symbian,没⽤过,不知道C库是什么 。
Codesourcery
Codesourcery推出的产品叫Sourcery G++ Lite Edition,其中基于command-line的编译器是免费的,在官⽹上可以下载,⽽其中包含的IDE和debug ⼯具是收费的,当然也有30天试⽤版本的。
⽬前CodeSourcery已经由明导国际(Mentor Graphics)收购,所以原本的⽹站风格已经全部变为 Mentor 样式,但是 Sourcery G++ Lite Edition 同样可以注册后免费下载。
Codesourcery⼀直是在做ARM⽬标 GCC 的开发和优化,它的ARM GCC在⽬前在市场上⾮常优秀,很多 patch 可能还没被gcc接受,所以还是应该直接⽤它的(⽽且他提供Windows下[mingw交叉编译的]和Linux下的⼆进制版本,⽐较⽅便;如果不是很有时间和兴趣,不建议下载 src 源码包⾃⼰编译,很⿇烦,Codesourcery给的shell脚本很多时候根本没办法直接⽤,得⾃⾏提取关键的部分⼿⼯执⾏,⼜费精⼒⼜费时间,如果想知道细节,其实不⽤⾃⼰编译⼀遍,看看他是⽤什么步骤构建的即可,如果你对交叉编译器感兴趣的话。
ABI 和 EABI
ABI:⼆进制应⽤程序接⼝(Application Binary Interface (ABI) for the ARM Architecture)。在计算机中,应⽤⼆进制接⼝描述了应⽤程序(或者其他类型)和操作系统之间或其他应⽤程序的低级接⼝。
EABI:嵌⼊式ABI。嵌⼊式应⽤⼆进制接⼝指定了⽂件格式、数据类型、寄存器使⽤、堆积组织优化和在⼀个嵌⼊式软件中的参数的标准约定。开发者使⽤⾃⼰的汇编语⾔也可以使⽤ EABI 作为与兼容的编译器⽣成的汇编语⾔的接⼝。
两者主要区别是,ABI是计算机上的,EABI是嵌⼊式平台上(如ARM,MIPS等)。
arm-linux-gnueabi-gcc 和 arm-linux-gnueabihf-gcc
两个交叉编译器分别适⽤于 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:
#include <stdio.h>
int main(void)
{
double a,b,c;
a = 23.543;
b = 323.234;
c = b/a;
printf(“the 13/2 = %f\n”, c);
printf(“hello world !\n”);
return 0;
}
1、使⽤ arm-linux-gnueabihf-gcc 编译,使⽤“-v”选项以获取更详细的信息:
# arm-linux-gnueabihf-gcc -v mfloat.c
COLLECT_GCC_OPTIONS=’-v’ ‘-march=armv7-a’ ‘-mfloat-abi=hard’ ‘-mfpu=vfpv3-d16′ ‘-mthumb’
-mfloat-abi=hard
可看出使⽤hard硬件浮点模式。
2、使⽤ arm-linux-gnueabi-gcc 编译:
# arm-linux-gnueabi-gcc -v mfloat.c
COLLECT_GCC_OPTIONS=’-v’ ‘-march=armv7-a’ ‘-mfloat-abi=softfp’ ‘-mfpu=vfpv3-d16′ ‘-mthumb’
-mfloat-abi=softfp
可看出使⽤softfp模式。
交叉编译⼯具
参考资料
1. 交叉编译器 arm-linux-gnueabi 和 arm-linux-gnueabihf 的区别:
2. arm-none-linux-gnueabi,arm-none-eabi 与arm-eabi 区别:
3. What's the difference between arm-linux- / arm-none-linux-gnueabi- / arm-fsl-linux-gnueabi- in LTIB?
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论