当前位置: 首页 > article >正文

【概念版】交叉编译相关介绍

一、参考资料

交叉编译器 arm-linux-gnueabi 和 arm-linux-gnueabihf 的区别
ARM交叉编译器GNUEABI、NONE-EABI、ARM-EABI、GNUEABIHF等的区别
Hi3516编译 OpenCV

二、相关介绍

模式适用架构编译器解释说明优点缺点
soft--浮点运算全部由软件层实现--
softfparmelgcc-arm-linux-gnueabisoft-float(软浮点),浮点运算使用FPU,函数传参使用普通寄存器(整型)-中断负荷小,函数参数需要转换成浮点的再计算
hardarmhfgcc-arm-linux-gnueabihfhard-float(硬浮点),浮点运算使用FPU,函数传参使用FPU寄存器性能最好中断负荷高

ABI和EABI

应用二进制接口(Application Binary Interface (ABI) for the ARM Architecture)。

在计算机中,应用二进制接口描述了应用程序(或者其他类型)和操作系统之间或其他应用程序的低级接口。ABI涵盖了各种细节,比如:

  • 数据类型的大小、布局和对齐;
  • 调用约定(控制着函数的参数如何传送以及如何接受返回值),例如,是所有的参数都通过栈传递,还是部分参数通过寄存器传递;哪个寄存器用于哪个函数参数;通过栈传递的第一个函数参数是最先push到栈上还是最后;
  • 系统调用的编码和一个应用如何向操作系统进行系统调用。

ABI不同于应用程序接口(API),API定义了源代码和库之间的接口,因此同样的代码可以在支持这个API的任何系统中编译,ABI允许编译好的目标代码在使用兼容ABI的系统中无需改动就能运行。一个完整的ABI,像Intel二进制兼容标准 (iBCS) ,允许支持它的操作系统上的程序不经修改即可在其他支持此ABI的操作系统上运行。

EABI是嵌入式平台上(如ARM,MIPS等),EABI与通用计算机的ABI的主要区别是应用程序代码中允许使用特权指令,不需要动态链接(有时是禁止的),和更紧凑的堆栈帧组织用来节省内存。广泛使用EABI的有Power PC和ARM。

VFP

从ARMv5开始,就有可选的 Vector Floating Point (VFP) 模块,当然最新的如 Cortex-A8, Cortex-A9 和 Cortex-A5 可以配置成不带VFP的模式供芯片厂商选择。
VFP经过若干年的发展,有VFPv2 (一些 ARM9 / ARM11)、 VFPv3-D16(只使用16个浮点寄存器,默认为32个)和VFPv3+NEON (如大多数的Cortex-A8芯片) 。对于包含NEON的ARM芯片,NEON一般和VFP共用寄存器。

FPU

硬件浮点运算单元

soft/softfp/hard 浮点运算模式

在gcc的编译参数上,使用 -mfloat-abi=<name> 来指定浮点运算处理方式,并使用 -mfpu=<name> 来指定浮点协处理的类型。

-mfloat-abi 包括 softsoftfphard 三种模式,其中后两者都要求ARM有 FPU浮点运算单元。在兼容性方面,soft与后两者是兼容的,但 softfp 和 hard 两种模式互不兼容。

-mfpu 可选类型如 fpa,fpe2,fpe3,maverick,vfp,vfpv3,vfpv3-fp16,vfpv3-d16,vfpv3-d16-fp16,vfpv3xd,vfpv3xd-fp16,neon,neon-fp16,vfpv4,vfpv4-d16,fpv4-sp-d16,neon-vfpv4等。

soft模式

在soft模式下,浮点运算全部由软件层实现。soft模式会存在不必要的浮点到整数、整数到浮点的转换,只适合于早期没有浮点计算单元的ARM处理器。

softfp模式

在softfp模式下,编译器会将浮点运算交给硬件浮点运算单元(FPU)处理,但函数参数的传递使用通用的整型寄存器而不是浮点寄存器。这种模式的优点是可以在支持硬件浮点运算的系统上提高浮点运算的性能,同时保持与不支持硬件浮点运算的系统的兼容性。

hard模式

在hard模式下,编译器会使用FPU来执行浮点运算,并且使用浮点寄存器将函数参数传递给FPU处理。这种模式的优点是可以充分利用硬件浮点运算的性能优势,尤其是在处理大量浮点运算的应用程序时。然而,hard模式生成的代码只能在支持硬件浮点运算的系统上运行,不兼容没有硬件浮点单元的系统。

armel和armhf 架构

softfp模式适用于armel架构,hard模式适用于armhf 架构。

armel 架构

armel(ARM EABI Little Endian)是ARM架构的一种,主要用于早期的ARM设备或者不带FPU 的设备。在这种架构下,浮点运算通常由软件模拟而非硬件直接执行,这可能会导致性能上的损失。armel架构的设备通常使用gcc编译器的softfp模式,这种模式将浮点计算交给FPU处理,但函数参数的传递使用通用的整型寄存器而不是FPU寄存器。

armhf 架构

armhf(ARM Hard Float)是ARM架构的另一种形式,主要用于较现代的ARM设备,这些设备至少实现了ARMv7架构,并且支持 第3版ARM矢量浮点规范(VFPv3)。armhf架构利用了硬件浮点运算,因此在浮点运算性能上相较于armel架构有显著提升。在编译时,armhf架构使用gcc编译器的hard模式,这种模式使用FPU浮点寄存器将函数参数传递给FPU处理。

在完全不改变源码和配置的情况下,在一些应用程序上,使用armhf能得到20%-25%的性能提升。对一些严重依赖于浮点运算的程序,更是可以达到300%的性能提升。

gnueabi和gnueabihf 交叉编译器

gnueabi和gnueabihf是两种用于编译ARM架构程序的交叉编译器,主要区别在于对浮点运算的支持和使用的C库版本。

在debian源里,这两种交叉编译器的定义如下:

gcc-arm-linux-gnueabi – The GNU C compiler for armel architecture
gcc-arm-linux-gnueabihf – The GNU C compiler for armhf architecture

gnueabi和gnueabihf两种交叉编译器分别适用于armel和armhf两种不同的架构,对待浮点运算采取了不同的策略。它们的gcc选项 -mfloat-abi 的默认值不同,分别采用softfp和hard模式。

gnueabi

特点:使用Glibc库,支持fork等函数。

适用场景:如果目标设备的浮点运算能力较弱,或者对浮点运算的性能要求不高,可以选择gnueabi。

gnueabihf

特点:使用hf(hard float)版本的Glibc库,支持硬件浮点运算。

适用场景:如果目标设备支持硬件浮点运算,并且对浮点运算的性能有较高要求,那么gnueabihf可能是更好的选择。

简单示例

把以下测试使用的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' '-shared-libgcc'  '-mfloat-abi=hard' '-mfpu=neon-vfpv4' '-mtls-dialect=gnu' '-mthumb' '-march=armv7-a+neon-vfpv4'

可看出使用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模式。

交叉编译工具链

下载交叉编译工具链:https://developer.arm.com/downloads/-/gnu-a

一次搞定 Arm Linux 交叉编译

Windows (mingw-w64-i686) hosted cross compilers

AArch32 bare-metal target (arm-none-eabi)

  • gcc-arm-10.3-2021.07-mingw-w64-i686-arm-none-eabi.tar.xz
  • gcc-arm-10.3-2021.07-mingw-w64-i686-arm-none-eabi.tar.xz.asc

AArch32 target with hard float (arm-none-linux-gnueabihf)

  • gcc-arm-10.3-2021.07-mingw-w64-i686-arm-none-linux-gnueabihf.tar.xz
  • gcc-arm-10.3-2021.07-mingw-w64-i686-arm-none-linux-gnueabihf.tar.xz.asc

AArch64 bare-metal target (aarch64-none-elf)

  • gcc-arm-10.3-2021.07-mingw-w64-i686-aarch64-none-elf.tar.xz
  • gcc-arm-10.3-2021.07-mingw-w64-i686-aarch64-none-elf.tar.xz.asc

AArch64 GNU/Linux target (aarch64-none-linux-gnu)

  • gcc-arm-10.3-2021.07-mingw-w64-i686-aarch64-none-linux-gnu.tar.xz
  • gcc-arm-10.3-2021.07-mingw-w64-i686-aarch64-none-linux-gnu.tar.xz.asc

x86_64 Linux hosted cross compilers

AArch32 bare-metal target (arm-none-eabi)

  • gcc-arm-10.3-2021.07-x86_64-arm-none-eabi.tar.xz
  • gcc-arm-10.3-2021.07-x86_64-arm-none-eabi.tar.xz.asc

AArch32 target with hard float (arm-none-linux-gnueabihf)

  • gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf.tar.xz
  • gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf.tar.xz.asc

AArch64 ELF bare-metal target (aarch64-none-elf)

  • gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz
  • gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz.asc

AArch64 GNU/Linux target (aarch64-none-linux-gnu)

  • gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz
  • gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz.asc

AArch64 GNU/Linux target (aarch64_be-none-linux-gnu)

  • gcc-arm-10.3-2021.07-x86_64-aarch64_be-none-linux-gnu.tar.xz
  • gcc-arm-10.3-2021.07-x86_64-aarch64_be-none-linux-gnu.tar.xz.asc

GCC (GNU Compiler Collection)

  • arm-linux-gnueabi-gcc:用于32位ARM体系结构的交叉编译工具链。
  • aarch64-linux-gnu-gcc:用于64位ARM体系结构的交叉编译工具链。
  • mips-linux-gnu-gcc:用于MIPS体系结构的交叉编译工具链。
  • x86_64-linux-gnu-gcc:用于x86-64体系结构的交叉编译工具链。

GCC 的命名规则为: arch [-vendor] [-os] [-(gnu)eabi]-gcc

解释说明

  • [] 的是可选部分。

  • arch: 芯片架构,如ARM,MIPS。

    • 32 位 Arm 架构:arm;
    • 64 位 Arm 架构:aarch64;
  • vendor :交叉编译工具链提供商,通常为none。

  • os :目标操作系统。根据对操作系统的支持与否,ARM GCC可分为支持和不支持操作系统,例如:

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

    • arm-none-linux-eabi:使用Linux,且使用Glibc

  • eabi:嵌入式应用二进制接口。

ARM GCC Toolchain

  • GNU Arm Embedded Toolchain:这是一个社区支持的预构建GNU编译器工具链,适用于基于ARM的CPU。它提供了针对不同主机操作系统(如GNU/Linux、Windows和macOS)的交叉工具链,支持裸机和Linux目标。

  • xPack GNU Arm Embedded GCC:这是一个跨平台的二进制分发版本,专为GNU Arm嵌入式GCC工具链设计。它支持Windows、macOS和GNU/Linux系统,提供了稳定、可重复使用的编译环境,适用于嵌入式系统开发、教育与研究以及开源项目。

  • ARM CMake Toolchains:这是一个CMake工具链配置项目,提供了针对不同ARM架构的工具链文件,如 arm-linux-gnueabihf.toolchain.cmakearm-none-eabi.toolchain.cmake,帮助CMake在交叉编译时正确选择编译器和工具链。

  • arm-none-eabi-gcc:这是一个用于编译ARM架构裸机系统(包括ARM Linux的boot、kernel)的工具链,不适用编译Linux应用程序。它适用于ARM7、Cortex-M和Cortex-R内核的芯片使用

  • arm-none-linux-gnueabi-gcc:这是一个主要用于基于ARM架构的Linux系统的工具链,可用于编译ARM架构的u-boot、Linux内核、Linux应用等。它基于GCC,使用Glibc库,经过Codesourcery公司优化过推出的编译器,适用于ARM9、ARM11、Cortex-A内核,带有Linux操作系统的情况

  • arm-linux-gnueabi-gccarm-linux-gnueabihf-gcc:这两个交叉编译器分别适用于armel和armhf两个不同的架构,对待浮点运算采取了不同的策略。它们是gcc的选项 -mfloat-abi 的默认值不同,分别采用softfp和hard模式

交叉编译基本配置

指定编译后的文件的安装目录:

--prefix=/usr/local/opencv-4.1.0

指定编译后使用文件的平台:

--host=arm-linux   	# arm
--host=x86-linux 	# x86
--host=arm-none-linux-gnueabi
--host=aarch64-linux-gnu

指定gcc/g++编译器:

CC=aarch64-linux-gnu-gcc 
CXX=aarch64-linux-gnu-g++ 

http://www.kler.cn/a/526340.html

相关文章:

  • .NET Core缓存
  • 6.进程的使用方式
  • 每日一题——序列化二叉树
  • 【解决方案】MuMu模拟器移植系统进度条卡住98%无法打开
  • 《DeepSeek 实用集成:大模型能力接入各类软件》
  • 探索AI(chatgpt、文心一言、kimi等)提示词的奥秘
  • 基于Java+Swing实现天气预报系统
  • Hive:窗口函数(1)
  • DeepSeek介绍
  • UE求职Demo开发日志#16 实现物品合成表读取和合成逻辑
  • [LeetCode]day4 977.有序数组的平方
  • 【Python】深入理解Python中的装饰器链:创建组合装饰器的技巧与实践
  • 【Block总结】动态蛇形卷积,专注于细长和弯曲的局部结构|即插即用
  • STM32 PWMI模式测频率占空比
  • (持续更新中~~)3、原来可以这样理解C语言_分⽀和循环上(3)条件操作符
  • 使用Python进行大模型的测试与部署
  • 8642 快速排序
  • 【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.18 逻辑运算引擎:数组条件判断的智能法则
  • Java中的注解与反射:深入理解getAnnotation(Class<T> annotationClass)方法
  • 在 Linux 上安装 Microsoft TrueType 字体:ttf-mscorefonts-installer 指南
  • 数据结构:线性表查找的三种方式
  • 向下调整算法(详解)c++
  • 指针空值——nullptr(C++11)——提升指针安全性的利器
  • Hive:静态分区(分区语法,多级分区,分区的查看修改增加删除)
  • 无公网IP 外网访问 本地部署夫人 hello-algo
  • 【赵渝强老师】K8s中Pod探针的TCPSocketAction