浅析arm历史和交叉编译链选择

技术应用 2年前 (2022) aysz01
0

众所周知ARM的设计是艾康计算机公司于1983年开始的开发项目。这个团队由RogerWilson和SteveFurber带领,着手开发一种类似高级6502架构的处理器。Acorn计算机有一大堆建构在6502处理器上的计算机,因此能设计出一颗类似的芯片即意味着对公司有很大的优势。

AcornRISCMachine:ARM2

用在BBCMicro上的ARM1secondprocessor

团队在1985年时开发出样本“ARM1”,而首颗真正能量产的“ARM2”于次年投产。ARM2具有32位的数据总线、26位的定址空间,并提供64Mbyte的定址范围与16个32-bit的寄存器。寄存器中有一个作为程序计数器,其前面6位和后面2位用来保存处理器状态标记。ARM2可能是全世界最简单实用的32位微处理器,仅容纳了30,000个晶体管(六年后的摩托罗拉68000包含了70,000颗)。之所以精简的原因在于它不含微码(这大概占了68000的晶体管数约1/4至1/3);而且与当时大多数的处理器相同,它没有包含任何的高速缓存。这个精简的特色使它只需消耗很少的电能,却能发挥比Intel80286更好的性能[10]。后继的处理器“ARM3”则备有4KB的高速缓存,使它能发挥更佳的性能。

Apple、DEC、Intel、Marvell:ARM6、StrongARM、XScale[编辑]

在1980年代晚期,苹果计算机开始与艾康计算机合作开发新版的ARM核心。由于这项目非常重要,艾康计算机甚至于1990年将设计团队另组成一间名为安谋国际科技(AdvancedRISCMachinesLtd.)的新公司。也基于这原因,使得ARM有时候反而称作AdvancedRISCMachine而不是AcornRISCMachine。由于其母公司ARMHoldingsplc于1998年在伦敦证券交易所和NASDAQ挂牌上市[11],使得AdvancedRISCMachines成了ARMLtd旗下拥有的产品[12]。

这个项目到后来进入“ARM6”,首版的样品在1991年发布,然后苹果计算机使用ARM6架构的ARM610来当作他们AppleNewton产品的处理器。在1994年,艾康计算机使用ARM610做为他们个人计算机产品的处理器。

在这些变革之后,内核部分却大多维持一样的大小——ARM2有30,000颗晶体管,但ARM6却也只增长到35,000颗。主要概念是以ODM的方式,使ARM核心能搭配一些选配的零件而制成一颗完整的CPU,而且可在现有的晶圆厂里制作并以低成本的方式达到很大的性能。

ARM的经营模式在于出售其IP核,授权厂家依照设计制作出建构于此核的微控制器和中央处理器。最成功的实现案例属ARM7TDMI,几乎卖出了数亿套内置微控制器的设备。

Digital曾购买这个架构的产权并研发出“StrongARM”。在233MHz的频率下,这颗CPU只消耗1瓦特的电能(后来的芯片消耗得更少)。这项设计后来为了和英特尔的控诉和解而技术移转,英特尔因而利用StrongARM架构补强他们老旧的i960产品。英特尔后来开发出他们自有的高性能架构产品XScale,之后卖给了迈威尔科技。

支持智能手机、个人数码助理和其他手持设备最常见的架构是“ARMv4”。XScale和ARM926处理器是“ARMv5TE”,而且比起建构在ARMv4的StrongARM、ARM925T和ARM7TDMI等处理器还更常见于许多高端设备上[来源请求]。

内核种类

ARMv1ARM1

ARMv2ARM2、ARM3

ARMv3ARM6、ARM7

ARMv4StrongARM、ARM7TDMI、ARM9TDMI

ARMv5ARM7EJ、ARM9E、ARM10E、XScale

ARMv6ARM11、ARMCortex-M

ARMv7ARMCortex-A、ARMCortex-M、ARMCortex-R

ARMv8(A)Cortex-A35、Cortex-A50系列[13]、Cortex-A72、Cortex-A73、Cortex-A75、Cortex-A76

架构

从1995年开始,《ARM体系结构参考手册》是ARM文档的主要来源,提供了关于ARM处理器架构和指令集,区分接口,所有的ARM处理器的支持(如指令语义)的实现细节可能会有所不同。该体系结构随着时间的演变,并与Cortex系列的核心开始,存在三个“配置”的定义如下:

"应用"配置:Cortex-A系列

"嵌入式"配置:Cortex-R系列

"微处理器"配置:ARMCortex-M系列。

每个配置允许有其子集的架构。

CPU模式

CPUARM架构指定了以下的CPU模式。在任何时刻,CPU只可处于某一种模式,但可由于外部事件(中断)或编程方式进行模式切换。

用户模式仅非特权模式。

系统模式仅无需例外进入的特权模式。仅以执行明确写入CPSR的模式位的指令进入。Supervisor(svc)模式在CPU被重置或者SWI指令被执行时进入的特权模式。

Abort模式预读取中断或数据中断异常发生时进入的特权模式。

未定义模式未定义指令异常发生时进入的特权模式。

干预模式处理器接受一条IRQ干预时进入的特权模式。

快速干预模式处理器接受一条IRQ干预时进入的特权模式。

Hyp模式armv-7a为cortex-A15处理器提供硬件虚拟化引进的管理模式。

最新的armv8Aarm64与aarch64

在找交叉编译链过程中被这三个困惑好久,在选择之前一定要先搞明白这三者的关系

ARM在2007年已着手设计工作,并于2011年11月公报ARMv8A64bit指令集架构,耗用了4年的研发时间。

ARMv8A分为A64及A32两个部分,A64顾名思义属于64bit的部份,主要存在于AARCH64的状态。而A32又称AARCH32状态,用作支持现有A32ARM指令集。ARM并没有采用AMDx86-64及IntelEM64T扩充32bit指令做法,而是选择全新开发专用的64bit指令。据ARM方面表示,这一做法与省电的考虑有关,当运行64biTISA时,ARMv7电路可处于闲置状态,节省功耗。同A64ISA也移除了作用不大的LDM/STM(load/storemulTIple)指令,改为LD/ST’P’指令,以降低复杂性及功耗,与此同时,32bit到64bit状态转换采用Inter-processing的做法,确保32bit到64bit指令皆可顺利执行。

armv8A架构又细分为armv8.2a、armv8.3a、armv8.4a、armv8.5a。

在今年的Computex上arm公布了2018年的Cortex-A旗舰CPU,Cortex-A76.这个CPU的微构架做了彻底的重新设计,它重点提高了峰值性能,同时良好地保持了性能功耗比。Cortex-A76将armCPU的性能推上了一个新高度。Cortex-A76还是armv8.2-a构架实现,与现有的处理兼容,还是使用DSU技术,到时微构架的重新设计使得它比Cortex-A75平均有35%的性能提升,且有40%的能耗比提升。对浮点数和机器学习运算任务提升最大。麒麟980用的性能核心就是公版Cortex-A76.

Cortex-A76是第一个开始逐渐去除32bit支持的CPU。A76还是支持aarch32,但是只是在最低特权级的EL0支持,而aarch64在EL0-EL3都支持-从OS到底层的固件。在将来某个时候,arm非常有可能完全只支持64bit,这取决于arm生态系统的发展。

arm授权方式

ARM公司本身并不靠自有的设计来制造或出售CPU,而是将处理器架构授权给有兴趣的厂家。ARM提供了多样的授权条款,包括售价与散播性等项目。对于授权方来说,ARM提供了ARM内核的集成硬件叙述,包含完整的软件开发工具(编译器、debugger、SDK),以及针对内含ARMCPU硅芯片的销售权。对于无晶圆厂的授权方来说,其希望能将ARM内核集成到他们自行研发的芯片设计中,通常就仅针对获取一份生产就绪的智财核心技术(IPCore)认证。

许多半导体公司持有ARM授权:Atmel、Broadcom、CirrusLogic、Freescale(于2004从摩托罗拉公司独立出来)、富士通、英特尔(借由和Digital的控诉调停)、IBM、NVIDIA、台湾新唐科技(NuvotonTechnology)、英飞凌、任天堂、恩智浦半导体(于2006年从飞利浦独立出来)、OKI电气工业、三星电子、Sharp、STMicroelectronics、德州仪器和VLSI等许多这些公司均拥有各个不同形式的ARM授权。虽然ARM的授权项目由保密合约所涵盖,在知识产权工业,ARM是广为人知最昂贵的CPU内核之一。单一的客户产品包含一个基本的ARM内核可能就需索取一次高达美金20万的授权费用。而若是牵涉到大量架构上修改,则费用就可能超过千万美元。

交叉编译链选择

以上都是废话,重点关注armv8a即可。armv8a分为aarch32与aarch64两种模式。因此在选择交叉编译链时一定要确定自己运行的arm设备是什么架构,什么模式。

从授权上,交叉编译链分为免费授权版和付费授权版。

免费版目前有三大主流工具商提供,第一是GNU(提供源码,自行编译制作),第二是Codesourcery,第三是Linora。

收费版有ARM原厂提供的armcc、IAR提供的编译器等等,因为这些价格都比较昂贵,不适合学习用户使用,所以不做讲述。

arm-none-linux-gnueabi-gcc:是Codesourcery公司(目前已经被Mentor收购)基于GCC推出的的ARM交叉编译工具。可用于交叉编译ARM(32位)系统中所有环节的代码,包括裸机程序、u-boot、Linuxkernel、filesystem和App应用程序。

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

aarch64-linux-gnu-gcc:是由Linaro公司基于GCC推出的的ARM交叉编译工具。可用于交叉编译ARMv864位目标中的裸机程序、u-boot、Linuxkernel、filesystem和App应用程序。

arm-none-elf-gcc:是Codesourcery公司(目前已经被Mentor收购)基于GCC推出的的ARM交叉编译工具。可用于交叉编译ARMMCU(32位)芯片,如ARM7、ARM9、Cortex-M/R芯片程序。

arm-none-eabi-gcc:是GNU推出的的ARM交叉编译工具。可用于交叉编译ARMMCU(32位)芯片,如ARM7、ARM9、Cortex-M/R芯片程序。

命名规则

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

arch–体系架构,如ARM,MIPS(通过交叉编译工具生成的可执行文件或系统镜像的运行平台或环境)

vendor–工具链提供商

os–目标操作系统(host主要操作平台,也就是编译时的系统)

eabi–嵌入式应用二进制接口(EmbeddedApplicaTIonBinaryInterface)

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

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

arm-none-linux-eabi:用于Linux的,使用Glibc

linaro交叉编译链简介

以下面的链接为例,分析下各个文件的作用。http://releases.linaro.org/components/toolchain/binaries/5.5-2017.10/aarch64-linux-gnu/。该目录下面列出了一些列的交叉编译工具:

gcc-linaro-5.5.0-2017.10-i686-mingw32_aarch64-linux-gnu.tar.xz27-Feb-201800:17234.0Mopen

运行在32位x86windows主机的aarch64支持linux系统的交叉编译链。

gcc-linaro-5.5.0-2017.10-i686_aarch64-linux-gnu.tar.xz27-Feb-201800:1789.0Mopen

运行在32位x86linux主机的aarch64位支持linux系统的交叉编译链。

gcc-linaro-5.5.0-2017.10-x86_64_aarch64-linux-gnu.tar.xz27-Feb-201800:1789.9Mopen

运行在64位linux主机的aarch64位支持linux系统的交叉编译链。这个正是我要找的交叉编译链。

runTIme-gcc-linaro-5.5.0-2017.10-aarch64-linux-gnu.tar.xz28-Jan-201817:326.2Mopen

runtime-gcc-linaro-5.5.0-2017.10-aarch64-linux-gnu.tar.xz.asc28-Jan-201817:3292open

sysroot-glibc-linaro-2.21-2017.10-aarch64-linux-gnu.tar.xz27-Feb-201800:1833.6Mopen

sysroot-glibc-linaro-2.21-2017.10-aarch64-linux-gnu.tar.xz.asc

这个runtime以及sysroot-glibc暂时不确定是做什么用的。

再补充点交叉编译链的东西:

实例

1、arm-none-eabi-gcc

(ARMarchitecture,novendor,nottargetanoperatingsystem,complieswiththeARMEABI)

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

2、arm-none-linux-gnueabi-gcc

(ARMarchitecture,novendor,createsbinariesthatrunontheLinuxoperatingsystem,andusestheGNUEABI)

主要用于基于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

AndroidARM编译器。

4、armcc

ARM公司推出的编译工具,功能和arm-none-eabi类似,可以编译裸机程序(u-boot、kernel),但是不能编译Linux应用程序。armcc一般和ARM开发工具一起,KeilMDK、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推出的产品叫SourceryG++LiteEdition,其中基于command-line的编译器是免费的,在官网上可以下载,而其中包含的IDE和debug工具是收费的,当然也有30天试用版本的。

目前CodeSourcery已经由明导国际(MentorGraphics)收购,所以原本的网站风格已经全部变为Mentor样式,但是SourceryG++LiteEdition同样可以注册后免费下载。

Codesourcery一直是在做ARM目标GCC的开发和优化,它的ARMGCC在目前在市场上非常优秀,很多patch可能还没被gcc接受,所以还是应该直接用它的(而且他提供Windows下[mingw交叉编译的]和Linux下的二进制版本,比较方便;如果不是很有时间和兴趣,不建议下载src源码包自己编译,很麻烦,Codesourcery给的shell脚本很多时候根本没办法直接用,得自行提取关键的部分手工执行,又费精力又费时间,如果想知道细节,其实不用自己编译一遍,看看他是用什么步骤构建的即可,如果你对交叉编译器感兴趣的话。

ABI和EABI

ABI:二进制应用程序接口(ApplicationBinaryInterface(ABI)fortheARMArchitecture)。在计算机中,应用二进制接口描述了应用程序(或者其他类型)和操作系统之间或其他应用程序的低级接口。

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

intmain(void)

{

doublea,b,c;

a=23.543;

b=323.234;

c=b/a;

printf(“the13/2=%fn”,c);

printf(“helloworld!n”);

return0;

}

1、使用arm-linux-gnueabihf-gcc编译,使用“-v”选项以获取更详细的信息:

arm-linux-gnueabihf-gcc-vmfloat.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-vmfloat.c

COLLECT_GCC_OPTIONS=’-v’‘-march=armv7-a’‘-mfloat-abi=softfp’‘-mfpu=vfpv3-d16′‘-mthumb’-mfloat-abi=softfp

可看出使用softfp模式。

版权声明:aysz01 发表于 2022-08-06 14:47:09。
转载请注明:浅析arm历史和交叉编译链选择 | 电工学习网

暂无评论

暂无评论...