【问题标题】:build for ARMv6 with gnueabihf使用 gnueabihf 为 ARMv6 构建
【发布时间】:2016-05-10 00:13:55
【问题描述】:

我尝试为 ARMv6 构建应用,但失败了。

我猜问题是工具链支持硬浮点,但 ARMv6 不支持。

好吧,首先我设置-march=armv6,编译失败。

/opt/gcc-linaro-arm-linux-gnueabihf-4.8-2014.03_linux/arm-linux-gnueabihf/libc/usr/include/bits/byteswap.h: In function ‘__bswap_32’: /opt/gcc-linaro-arm-linux-gnueabihf-4.8-2014.03_linux/arm-linux-gnueabihf/libc/usr/include/bits/byteswap.h:45:1: sorry, unimplemented: Thumb-1 hard-float VFP ABI

另外,我设置了 -mfloat-abi=soft 这让链接器抱怨:

/opt/gcc-linaro-arm-linux-gnueabihf-4.8-2014.03_linux/bin/../lib/gcc/arm-linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld: error: prog uses VFP register arguments, prog.o does not /opt/gcc-linaro-arm-linux-gnueabihf-4.8-2014.03_linux/bin/../lib/gcc/arm-linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld: failed to merge target specific data of file prog.o

那么,我实际上如何为 ARMv6 构建? 还是工具链中存在错误?

【问题讨论】:

  • 您使用的是 Linux 吗? Linaro 适用于 Linux OS/glibc,除非您使用 -ffreestanding 编译,否则您将遇到问题。如果你真的是嵌入式的,我建议你使用a newlib compiler。启动板有多个针对不同主机的构建(包括 Linux 主机开发盒)。否则,您可能会使用标签“embedded-linux”。

标签: gcc linker arm embedded armv6


【解决方案1】:

您的工具链默认配置为发出 Thumb 代码。问题在于浮点指令的唯一 Thumb 编码是 32 位 Thumb-2 编码,从所有意图和目的来看,它只存在于 ARMv7 或更高版本*,当然不是在普通 ARMv6 上可用。

要针对 v7 之前的架构,最好使用 -marm 编译以生成 ARM 代码,而不是相对有限的 16 位 Thumb 指令集。

* 我怀疑大多数人永远不会故意遇到 ARM1156。

【讨论】:

  • 太好了,谢谢。作为对您帖子的补充:除了使用 -marm 之外,我确实退出了 -mfloat-abi=soft。
  • @b-boy 这是一个 gnueabihf 工具链,所以是的,捆绑的库只会链接到硬浮动对象。它们可能也是 Thumb-2,所以也不要静态链接;确实,您希望针对目标设备的 sysroot 构建,而不是与工具链捆绑的最小系统,以避免令人讨厌的意外和/或细微的不兼容性。
  • BCM2835 SoC 中的 ARM1176JZF-S 内核(用于某些 Raspberry Pi 型号)是 ARMv6z,其中包括通过 VFPv2 的硬浮点支持。
【解决方案2】:

BCM2835 SoC 中的ARM1176JZF-S 内核(在某些 Raspberry Pi 型号上使用)是 ARMv6z 架构,其中包括通过 VFPv2 提供的硬浮点支持,因此这绝对是一个有效的目标配置。

问题在于 Linaro 工具链的维护者将 ARMv7A 指定为最低支持架构。它使得使用 Debian 交叉编译器包对 Raspberry Pi 进行交叉编译相当无望,因为如果您使用 -march=armv6z -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard 正确配置 BCM2835 的构建,各种内置将失败。

这是 Raspbian Stretch 上的 gcc -v

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/6/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Raspbian 6.3.0-18+rpi1+deb9u1' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-6 --program-prefix=arm-linux-gnueabihf- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-armhf/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-armhf --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-armhf --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-sjlj-exceptions --with-arch=armv6 --with-fpu=vfp --with-float=hard --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
Thread model: posix
gcc version 6.3.0 20170516 (Raspbian 6.3.0-18+rpi1+deb9u1) 

与 Ubuntu 18.04 上的 arm-linux-gnueabi-gcc-6 -v 相比:

$ arm-linux-gnueabihf-gcc-6 -v
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-gcc-6
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabihf/6/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 6.4.0-17ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++ --prefix=/usr --with-as=/usr/bin/arm-linux-gnueabihf-as --with-ld=/usr/bin/arm-linux-gnueabihf-ld --program-suffix=-6 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --disable-werror --enable-multilib --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-linux-gnueabihf --program-prefix=arm-linux-gnueabihf- --includedir=/usr/arm-linux-gnueabihf/include
Thread model: posix
gcc version 6.4.0 20180424 (Ubuntu/Linaro 6.4.0-17ubuntu1)

并注意前者有--with-arch=armv6 --with-fpu=vfp --with-float=hard,而后者有--with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard This blog post 提供了一种解决方案(基本上使用 Clang 和自建 binutils):

【讨论】:

  • 我想知道如何使用 arm-linux-gnueabihf 为 Pi 零编译树莓派 linux 内核,如下所述:raspberrypi.org/documentation/linux/kernel/building.md,从那以后有什么变化吗?
  • @axk 我也在考虑这个问题。在我的 Pi Zero 上,我无法运行使用 crossbuild-essential-armhf 交叉编译的二进制文件,但由于某些未知原因,我可以愉快地运行使用相同交叉工具链构建的内核。
  • @itachi,原因是内核没有任何外部依赖项,并且通过您的常规用户空间应用程序编译,您至少拥有 glibc 和加载程序。问题是,当您编译它时使用 armv7 glibc,这会强制您的应用程序重新定位到 armv7。确保您编译的所有依赖项都具有正确的目标架构的技巧。
  • @axk 是的,我昨天一直坐到很晚,终于解决了这个问题。 “问题”是在链接阶段。当我使用 -march-mcpu 等所有标志交叉编译我的二进制文件而不链接时,然后针对这个二进制文件运行 readelf,架构部分看起来与在 RPi 上编译的相同代码完全相同。但是,链接后,一切看起来都像 armv7。我认为唯一的解决方案是自己编译 ARM GCC 工具链,针对 armv6(至少对于旧的 Pies 和 Zero)。
猜你喜欢
  • 1970-01-01
  • 2011-10-23
  • 1970-01-01
  • 2011-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-23
  • 1970-01-01
相关资源
最近更新 更多