GNU ARM Toolchain入门指南

  1. 典型的工具链

如上图所示, 整个过程分为三个步骤: 编译, 链接, 重定位

Step 1: 交叉编译

在这一步骤中, 所有的源文件都是基于高级语言(C or C++)进行编写的, 是从高级语言转换为机器可以理解的机器码。 

Step 2: 链接目标文件

在单个文件被编译成目标文件后, 接下来是将它们链接倒一个二进制文件中。 一般来讲, 编写的代码通常被分为3个段, .text (加载我们所写的代码), .data (初始化的全局变量), .bss(未初始化的全局变量)

在这里有一个不得不提的二进制工具集 - GNU Binutils. GNU Binutils, 即GNU Binary Utilities的简写, 是一组二进制工具的集合。 主要包含的工具有:

  • ld: 链接器, 将多个目标文件链接成一个可执行文件/目标库文件
  • as: 汇编器, 将汇编源代码编译为机器代码
  • ranlib: 对静态库的符号索引表进行更新
  • add2line: 将地址转换为行号 (一般用于反汇编)
  • ar: 用来操作.a档案文件, 如创建, 修改, 提取内容等
  • nm: 列出目标文件中的符号
  • objcopy: 拷贝并转换文件, 可用于不同格式的二进制文件转换
  • objdump: 显示目标文件中的信息
  • readelf: 显示ELF格式的目标文件信息
  • size: 显示目标文件或者档案文件的节(section)大小
  • strings: 显示文件中可打印字符串信息。 

Step 3: 重定向二进制文件

  2. ToolChain简介

  交叉编译工具链是一个由编译器, 连接器和解释器组成的综合开发环境, 交叉编译工具链只要由binutils, gcc和glibc三个部分组成

  • 从授权上, 分为免费授权版和付费授权版。 

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

  收费版有ARM原厂提供的armcc, IAR提供的编译器等等

   交叉编译工具链的命名规则: arch [-vendor] [-kernel][-system]
  arch: 体系架构, 如ARM, MIPS
  vendor: 工具链提供商
  kernel: 目标内核
    • Linux: 表示有操作系统(主要指Linux)的环境
    • bare-metal: 表示无操作系统的环境。 比如u-boot, 跑马灯的小程序
  system: 目标系统: 一般为(gnu)eabi, 即嵌入式应用二进制接口 (Embedded Application Binary Interface)
  另外 ARM GCC可以根据是否支持操作系统进行分类, 如:
  • arm-none-eabi: 该编译器没有操作系统, 不能支持那些与操作系统关系密切的函数。 
  • arm-none-linux-eabi: 该编译器用于Linux系统。 

3. 交叉编译工具链举例

  • arm-none-eabi-gcc:  

    arch: arm    vendor: none    kernel: empty     system: eabi

    该编译器一般用于编译ARM架构的裸机系统(包括ARM Linux的boot, kernel, 不适用编译Linux应用Application), 一般适合ARM7, Cortex-M和Cortex-R内核的芯片适用。 所以不支持那些和操作系统关系密切的函数。 

  • arm-none-linux-gnueabi-gcc

   arch: arm      vendor: none    kernel: linux      system: gnueabi

    该编译器主要用于基本ARM架构的Linux系统, 可用于编译ARM架构的u-boot, Linux内核, Linux应用等。 arm-none-linux-gnueabi基于gcc, 使用glibc库。 是经过Codesourcery公司优化过推出的编译器, 且该交叉编译工具的浮点运算非常优秀, 一般ARM9, ARM11, Cortex-A内核, 带有Linux操作系统的会用到。 

  • arm-eabi-gcc

    该编译器是Android ARM编译器。 

  • arm-linux-gnueabi-gcc  VS arm-linux-gnueabihf-gcc

    这两个交叉编译名称上的区别在于gnueabi与gnueabihf, 分别适用于armel和armhf两个不同的架构, armel和armhf这两种架构在浮点运算上采用了不同的策略 (有fpu的arm才能支持这两种浮点策略)。 这两个交叉编译器只有在gcc的选项 -mfloat-abi的默认值不同。 gcc的选项 -mfloat-abi有三种值: soft, softfp, hard. 

    a. soft: 不用fpu进行浮点计算

    b. softfp: armel架构 (arm-linux-gnueabi-gcc)的默认值, 用fpu计算, 但传参数时使用普通寄存器。 这样中断的时候, 只需要保存普通寄存器, 且中断负荷小, 但参数需要转换成浮点数之后再计算。 

    c. hard: armhf架构 (arm-linux-gnueabihf-gcc)的默认值, 用fpu计算, 传参数也用fpu中的浮点寄存器传递。 这样省去了转换, 性能最好,但中断负荷高。 

4. 链接 

  https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads

  https://www.plm.automation.siemens.com/global/en/products/embedded-software/sourcery-toolchain-services.html

  https://www.linaro.org/

5.  补充

  a. 在讲解各编译器之前, 必须先了解一下以下这些文件。

    .o 文件: 指的是object文件, 俗称目标文件。 在Linux下 .o, Windows下 .obj

    .a 文件: 指的是archive文件, 俗称静态库文件。 在Linux下 .a, Windows下 .lib

    .so文件: 指的是shared object文件, 用于动态连接的。 在Linux下 .so,  Windows下 .dll. 

  b. 对于交叉编译工具链,其中几个参数

    --build=编译该软件所使用的平台

    --host=该软件将运行的平台

    --target=该软件所要处理的目标平台

b

 

posted @ 2023-09-26 22:12  球球小世界  阅读(576)  评论(0编辑  收藏  举报