ARM 编译工具链详解
GNU Arm Embedded Toolchain 是用于 C/C++ 和汇编编程的即用型开源工具套件。GNU Arm 嵌入式开发工具链适用于 32 位 Arm Cortex-A,Arm Cortex-R 和 Arm Cortex-M 处理器系列。GNU Arm 嵌入式工具链包括 GNU 编译器 (GCC),可直接从 Arm 官方免费获得,用于在 Windows,Linux 和 Mac OS X 操作系统上进行嵌入式软件开发。
官网: https://developer.arm.com/downloads/-/gnu-rm
1. 工具链命名规则
根据对操作系统的支持与否,工具链可分为支持和不支持操作系统。
例如 arm-none-eabi,arm-none-linux-eabi。下面我们来详细讲解工具链的命名规则与工具链之间的联系。
1.1 arm-none-eabi
即 ARM architecture,no vendor,not target an operaTIng system,complies with the ARM EABI 是不支持操作系统的,自然无法使用那些跟操作系统关系密切的函数,比如 fork(2)
。该工具链使用的是 newlib
这个专用于嵌入式系统的 C
库。
主要用于编译 ARM 架构的裸机系统(包括 ARM Linux 的 boot,kernel,不适用编译 Linux 应用 ApplicaTIon),一般适合 ARM7,Cortex-M 和 Cortex-R 内核架构的芯片开发使用,所以不支持与操作系统关系密切的函数。
1.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 操作系统的会用到这个工具链。
1.3 arm-eabi-gcc
用于 Android ARM 的编译器。
1.4 armcc
ARM 公司推出的编译工具,功能和 arm-none-eabi 类似,可以编译裸机程序(u-boot,kernel),但是无法编译 Linux 应用程序。armcc 一般和 ARM 开发工具集成在一起(即打造成 IDE),例如 Keil MDK,ADS,RVDS 和 DS-5 中的编译器都是集成 armcc 工具链,所以集成 armcc 编译器都是收费的。
1.5 ABI 和 EABI
在编译工具链的命名中总能看到 eabi
,这到底是什么意思呢。
ABI: 二进制应用程序接口(Application Binary Interface (ABI) for the ARM Architecture)。在计算机中,应用二进制接口描述了应用程序(或者其他类型)和操作系统之间或其他应用程序的低级接口。
EABI: 嵌入式 ABI。嵌入式应用二进制接口指定了文件格式,数据类型,寄存器使用,堆积组织优化和在一个嵌入式软件中的参数的标准约定。开发者使用自己的汇编语言也可以使用 EABI 作为与兼容的编译器生成的汇编语言的接口。
区别: ABI 应用于标准计算机,EABI 应用于是嵌入式计算机(如ARM,MIPS 等)。
2. 工具链包含工具集合
在 Windows 使用的是 gcc-arm-none-eabi,下载并安装好后,可以在它的安装目录 bin
文件夹下看到工具链包含 30 个工具,所以虽然 gcc-arm-none-eabi 名称开头是 gcc
但它不仅仅是一个 gcc
编译器,准确说是一套编译工具链,工具链包含的工具如下图。
接下来我们一起来看看我们频繁需要使用的部分工具以及这些工具的作用。
3. 工具链常用工具介绍
3.1 arm-none-eabi-gcc
这个工具为 C
语言编译器,可以将 .c
文件转化为 .o
的执行文件,编译命令如下。
arm-none-eabi-gcc -c hello.c
3.2 arm-none-eabi-g++
这个工具为 C++
编译器,可以将 .cpp
文件转化为 .o
的执行文件,使用方式如下。
arm-none-eabi-g++ hello.cpp -o helloworld
3.3 arm-none-eabi-ld
这个工具为链接器即最后链接所有 .o
文件生成最终可执行文件的工具。一般我们不使用链接器的指令来调用链接器链接文件,而是通过使用 arm-none-eabi-gcc
来调用,因为我们自己执行命令调用链接对 C/C++
文件混合型生成的 .o
文件的支持性不好,所以官方的说明书中也推荐使用 arm-none-eabi-gcc 指令来代替arm-none-eabi-ld 命令如下。
arm-none-eabi-gcc -o hello hello.o
3.4 arm-none-eabi-objcopy
此工具将链接器生成的文件转化为 .bin/.hex
等烧写的格式,用以下载进入单片机,命令如下。
arm-none-eabi-objcopy hello hello.bin
3.5 arm-none-eabi-gdb
工具链中的调试器,将它连接到调试器硬件产生的网络端口,就可以进行硬件和代码的调试了。GDB 是 GNU 下的调试软件,它具有很多自己的特性,可能无法想象使用命令行调试的景象。
4. 总结
ARM 交叉编译工具链由交叉编译器(例如 gcc,g++,ld),For ARM 的 C 库和二进制工具(例如 objcopy,objdump)这 3 个部分组成。
(1) 其中二进制工具由 GNU Binutils 提供。
(2) 其中 For ARM 的 C 库由 glibc/uclibc 提供。
(3) 交叉编译器由 GNU 组织提供。