嵌入式技术
arm的历史
ARM的设计是艾康计算机公司于1983年开始的开发项目。
这个团队由Roger Wilson和Steve Furber带领,着手开发一种类似高级6502架构的处理器。Acorn计算机有一大堆建构在6502处理器上的计算机,因此能设计出一颗类似的芯片即意味着对公司有很大的优势。
Acorn RISC Machine:ARM2
用在BBC Micro上的ARM1 second processor
团队在1985年时开发出样本“ARM1”,而首颗真正能量产的“ARM2”于次年投产。ARM2具有32位的数据总线、26位的定址空间,并提供64 Mbyte的定址范围与16个32-bit的寄存器。寄存器中有一个作为程序计数器,其前面6位和后面2位用来保存处理器状态标记。ARM2可能是全世界最简单实用的32位微处理器,仅容纳了30,000个晶体管(六年后的摩托罗拉68000包含了70,000颗)。之所以精简的原因在于它不含微码(这大概占了68000的晶体管数约1/4至1/3);而且与当时大多数的处理器相同,它没有包含任何的高速缓存。这个精简的特色使它只需消耗很少的电能,却能发挥比Intel 80286更好的性能[10]。后继的处理器“ARM3”则备有4KB的高速缓存,使它能发挥更佳的性能。
Apple、DEC、Intel、Marvell:ARM6、StrongARM、XScale[编辑]
在1980年代晚期,苹果计算机开始与艾康计算机合作开发新版的ARM核心。由于这项目非常重要,艾康计算机甚至于1990年将设计团队另组成一间名为安谋国际科技(Advanced RISC Machines Ltd.)的新公司。也基于这原因,使得ARM有时候反而称作Advanced RISC Machine而不是Acorn RISC Machine。由于其母公司ARM Holdings plc于1998年在伦敦证券交易所和NASDAQ挂牌上市[11],使得Advanced RISC Machines成了ARM Ltd旗下拥有的产品[12]。
这个项目到后来进入“ARM6”,首版的样品在1991年发布,然后苹果计算机使用ARM6架构的ARM 610来当作他们Apple Newton产品的处理器。在1994年,艾康计算机使用ARM 610做为他们个人计算机产品的处理器。
在这些变革之后,内核部分却大多维持一样的大小——ARM2有30,000颗晶体管,但ARM6却也只增长到35,000颗。主要概念是以ODM的方式,使ARM核心能搭配一些选配的零件而制成一颗完整的CPU,而且可在现有的晶圆厂里制作并以低成本的方式达到很大的性能。
ARM的经营模式在于出售其IP核,授权厂家依照设计制作出建构于此核的微控制器和中央处理器。最成功的实现案例属ARM7TDMI,几乎卖出了数亿套内置微控制器的设备。
Digital曾购买这个架构的产权并研发出“StrongARM”。在233 MHz的频率下,这颗CPU只消耗1瓦特的电能(后来的芯片消耗得更少)。这项设计后来为了和英特尔的控诉和解而技术移转,英特尔因而利用StrongARM架构补强他们老旧的i960产品。英特尔后来开发出他们自有的高性能架构产品XScale,之后卖给了迈威尔科技。
支持智能手机、个人数码助理和其他手持设备最常见的架构是“ARMv4”。XScale和ARM926处理器是“ARMv5TE”,而且比起建构在ARMv4的StrongARM、ARM925T和ARM7TDMI等处理器还更常见于许多高端设备上[来源请求]。
内核种类
ARMv1 ARM1
ARMv2 ARM2、ARM3
ARMv3 ARM6、ARM7
ARMv4 StrongARM、ARM7TDMI、ARM9TDMI
ARMv5 ARM7EJ、ARM9E、ARM10E、XScale
ARMv6 ARM11、ARM Cortex-M
ARMv7 ARM Cortex-A、ARM Cortex-M、ARM Cortex-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 系列
"微处理器"配置: ARM Cortex-M 系列。
每个配置允许有其子集的架构。
CPU模式
CPU ARM架构指定了以下的CPU模式。在任何时刻,CPU只可处于某一种模式,但可由于外部事件(中断)或编程方式进行模式切换。
用户模式仅非特权模式。
系统模式仅无需例外进入的特权模式。仅以执行明确写入CPSR的模式位的指令进入。Supervisor (svc) 模式在CPU被重置或者SWI指令被执行时进入的特权模式。
Abort 模式预读取中断或数据中断异常发生时进入的特权模式。
未定义模式未定义指令异常发生时进入的特权模式。
干预模式处理器接受一条IRQ干预时进入的特权模式。
快速干预模式处理器接受一条IRQ干预时进入的特权模式。
Hyp 模式armv-7a为cortex-A15处理器提供硬件虚拟化引进的管理模式。
最新的armv8A arm64 与aarch64
在找交叉编译链过程中被这三个困惑好久,在选择之前一定要先搞明白这三者的关系
ARM在2007年已着手设计工作,并于2011年11月公报ARMv8A 64bit指令集架构,耗用了4年的研发时间。
ARMv8A分为A64及A32两个部分,A64顾名思义属于64bit的部份,主要存在于AARCH64的状态。而A32又称AARCH32状态,用作支持现有A32 ARM指令集。ARM并没有采用AMD x86-64及Intel EM64T扩充32bit指令做法,而是选择全新开发专用的64bit指令。据ARM方面表示,这一做法与省电的考虑有关,当运行64bit ISA时,ARMv7电路可处于闲置状态,节省功耗。同A64 ISA也移除了作用不大的LDM/STM(load/store multiple)指令,改为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将arm CPU的性能推上了一个新高度。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非常有可能完全只支持64 bit,这取决于arm生态系统的发展。
arm授权方式
ARM公司本身并不靠自有的设计来制造或出售CPU,而是将处理器架构授权给有兴趣的厂家。ARM提供了多样的授权条款,包括售价与散播性等项目。对于授权方来说,ARM提供了ARM内核的集成硬件叙述,包含完整的软件开发工具(编译器、debugger、SDK),以及针对内含ARM CPU硅芯片的销售权。对于无晶圆厂的授权方来说,其希望能将ARM内核集成到他们自行研发的芯片设计中,通常就仅针对获取一份生产就绪的智财核心技术(IP Core)认证。
许多半导体公司持有ARM授权:Atmel、Broadcom、Cirrus Logic、Freescale(于2004从摩托罗拉公司独立出来)、富士通、英特尔(借由和Digital的控诉调停)、IBM、NVIDIA、台湾新唐科技(Nuvoton Technology)、英飞凌、任天堂、恩智浦半导体(于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、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芯片程序。
命名规则
交叉编译工具链的命名规则为:arch [-vendor] [-os] [-(gnu)eabi]
arch – 体系架构,如ARM,MIPS(通过交叉编译工具生成的可执行文件或系统镜像的运行平台或环境)
vendor – 工具链提供商
os – 目标操作系统(host主要操作平台,也就是编译时的系统)
eabi – 嵌入式应用二进制接口(Embedded Application Binary Interface)
根据对操作系统的支持与否,ARM GCC可分为支持和不支持操作系统,如
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-2018 00:17234.0Mopen
运行在32位x86windows主机的aarch64支持linux系统的交叉编译链。
gcc-linaro-5.5.0-2017.10-i686_aarch64-linux-gnu.tar.xz27-Feb-2018 00:1789.0Mopen
运行在32位x86linux主机的aarch64位支持linux系统的交叉编译链。
gcc-linaro-5.5.0-2017.10-x86_64_aarch64-linux-gnu.tar.xz27-Feb-2018 00:1789.9Mopen
运行在64位linux主机的aarch64位支持linux系统的交叉编译链。这个正是我要找的交叉编译链。
runtime-gcc-linaro-5.5.0-2017.10-aarch64-linux-gnu.tar.xz28-Jan-2018 17:326.2Mopen
runtime-gcc-linaro-5.5.0-2017.10-aarch64-linux-gnu.tar.xz.asc28-Jan-2018 17:3292open
sysroot-glibc-linaro-2.21-2017.10-aarch64-linux-gnu.tar.xz27-Feb-2018 00:1833.6Mopen
sysroot-glibc-linaro-2.21-2017.10-aarch64-linux-gnu.tar.xz.asc
这个runtime以及sysroot-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
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模式。
编辑:hfy
全部0条评论
快来发表一下你的评论吧 !