如何解决因警告“在PIE中创建DT_TEXTREL”而引起的ARM链接失败?
我想让 [firmware][1] 在Gentoo上构建,因为我正在为PocketBeagle2 [PB2][2] 构建一个Gentoo镜像。
然而,我遇到了下面显示的链接器错误。
我用crossdev安装了工具链,aarch64-unknown-linux-gnu-。希望有人能给出一些想法。
Here's the line I'm using to compile the project, which is the same line used to compile this project on Debian in the official BeagleBone repos for this board:
$ make V=1 -j4 CROSS_COMPILE=aarch64-unknown-linux-gnu- CFLAGS= LDFLAGS=-Wl,-V ARCH=aarch64 PLAT=k3 SPD=opteed K3_USART=0x6 BL32_BASE=80080000 PRELOADED_BL33_BASE=0x82000000 TARGET_BOARD=lite all
下面是结果:
make: Entering directory '/home/pepp/workspace/ddt/pocketbeagle-2-gentoo/trusted-firmware-a'
Including services/spd/opteed/opteed.mk
Building k3
MD /home/pepp/workspace/ddt/pocketbeagle-2-gentoo/trusted-firmware-a/build/k3/lite/release/libc
CC lib/libc/abort.c
CC lib/libc/assert.c
CC lib/libc/exit.c
CC lib/libc/memchr.c
CC lib/libc/memcmp.c
CC lib/libc/memcpy.c
CC lib/libc/memcpy_s.c
CC lib/libc/memmove.c
CC lib/libc/memrchr.c
CC lib/libc/printf.c
CC lib/libc/putchar.c
CC lib/libc/puts.c
CC lib/libc/qsort.c
CC lib/libc/snprintf.c
CC lib/libc/strchr.c
CC lib/libc/strcmp.c
CC lib/libc/strcpy_secure.c
CC lib/libc/strlcat.c
CC lib/libc/strlcpy.c
CC lib/libc/strlen.c
CC lib/libc/strnlen_secure.c
CC lib/libc/strncmp.c
CC lib/libc/strnlen.c
CC lib/libc/strrchr.c
CC lib/libc/strtok.c
CC lib/libc/strtoul.c
CC lib/libc/strtoll.c
CC lib/libc/strtoull.c
CC lib/libc/strtol.c
CC lib/libc/memset.c
AS lib/libc/aarch64/setjmp.S
MD /home/pepp/workspace/ddt/pocketbeagle-2-gentoo/trusted-firmware-a/build/k3/lite/release/lib
AR /home/pepp/workspace/ddt/pocketbeagle-2-gentoo/trusted-firmware-a/build/k3/lite/release/lib/libc.a
MD /home/pepp/workspace/ddt/pocketbeagle-2-gentoo/trusted-firmware-a/build/k3/lite/release/bl31
CC bl31/bl31_context_mgmt.c
CC bl31/bl31_main.c
CC bl31/bl31_traps.c
CC bl31/interrupt_mgmt.c
CC common/bl_common.c
CC common/runtime_svc.c
CC common/tf_log.c
CC drivers/arm/gic/v3/arm_gicv3_common.c
CC drivers/arm/gic/v3/gic-x00.c
CC drivers/arm/gic/v3/gicdv3_helpers.c
CC drivers/arm/gic/v3/gicrv3_helpers.c
CC drivers/arm/gic/v3/gicv3_helpers.c
CC drivers/arm/gic/v3/gicv3_main.c
CC drivers/console/multi_console.c
CC drivers/ti/ipc/sec_proxy.c
CC drivers/ti/ti_sci/ti_sci.c
CC lib/compiler-rt/builtins/popcountdi2.c
CC lib/compiler-rt/builtins/popcountsi2.c
CC lib/cpus/errata_common.c
CC lib/cpus/errata_report.c
CC lib/el3_runtime/aarch64/context_mgmt.c
CC lib/el3_runtime/cpu_data_array.c
CC lib/el3_runtime/simd_ctx.c
CC lib/extensions/mpam/mpam.c
CC lib/extensions/pmuv3/aarch64/pmuv3.c
CC lib/extensions/spe/spe.c
CC lib/extensions/sve/sve.c
CC lib/locks/bakery/bakery_lock_normal.c
CC lib/per_cpu/per_cpu.c
CC lib/psci/psci_common.c
CC lib/psci/psci_main.c
CC lib/psci/psci_mem_protect.c
CC lib/psci/psci_off.c
CC lib/psci/psci_on.c
CC lib/psci/psci_setup.c
CC lib/psci/psci_suspend.c
CC lib/psci/psci_system_off.c
CC lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
CC lib/xlat_tables_v2/xlat_tables_context.c
CC lib/xlat_tables_v2/xlat_tables_core.c
CC lib/xlat_tables_v2/xlat_tables_utils.c
CC plat/common/aarch64/plat_common.c
CC plat/common/plat_bl_common.c
CC plat/common/plat_gicv3.c
CC plat/common/plat_log_common.c
CC plat/common/plat_psci_common.c
CC plat/ti/common/k3_console.c
CC plat/ti/common/k3_gicv3.c
CC plat/ti/common/ti_bl31_setup.c
CC plat/ti/k3/common/k3_bl31_setup.c
CC plat/ti/k3/common/k3_psci.c
CC plat/ti/k3/common/k3_topology.c
CC services/arm_arch_svc/arm_arch_svc_setup.c
CC services/spd/opteed/opteed_common.c
CC services/spd/opteed/opteed_main.c
CC services/spd/opteed/opteed_pm.c
CC services/std_svc/std_svc_setup.c
AS bl31/aarch64/bl31_entrypoint.S
AS bl31/aarch64/crash_reporting.S
AS bl31/aarch64/runtime_exceptions.S
AS common/aarch64/debug.S
AS drivers/ti/uart/aarch64/16550_console.S
AS lib/aarch64/cache_helpers.S
AS lib/aarch64/misc_helpers.S
AS lib/cpus/aarch64/cortex_a53.S
AS lib/cpus/aarch64/cortex_a72.S
AS lib/cpus/aarch64/cpu_helpers.S
AS lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S
AS lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
AS lib/el3_runtime/aarch64/context.S
AS lib/locks/exclusive/aarch64/spinlock.S
AS lib/per_cpu/aarch64/per_cpu_asm.S
AS lib/psci/aarch64/psci_helpers.S
AS lib/xlat_tables_v2/aarch64/enable_mmu.S
AS plat/common/aarch64/platform_helpers.S
AS plat/common/aarch64/platform_mp_stack.S
AS plat/ti/common/k3_helpers.S
AS services/spd/opteed/opteed_helpers.S
MD /home/pepp/workspace/ddt/pocketbeagle-2-gentoo/trusted-firmware-a/build/k3/lite/release/bl31/bl31
CPP bl31/bl31.ld.S
LD /home/pepp/workspace/ddt/pocketbeagle-2-gentoo/trusted-firmware-a/build/k3/lite/release/bl31/bl31.elf
GNU ld (Gentoo 2.46.0 p1) 2.46.0
Supported emulations:
aarch64linux
aarch64linuxb
aarch64linux32
aarch64linux32b
armelfb_linux_eabi
armelf_linux_eabi
aarch64elf
aarch64elf32
aarch64elf32b
aarch64elfb
armelf
armelfb
/usr/x86_64-pc-linux-gnu/aarch64-unknown-linux-gnu/binutils-bin/2.46.0/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
make: *** [Makefile:1010: /home/pepp/workspace/ddt/pocketbeagle-2-gentoo/trusted-firmware-a/build/k3/lite/release/bl31/bl31.elf] Error 1
make: Leaving directory '/home/pepp/workspace/ddt/pocketbeagle-2-gentoo/trusted-firmware-a'
我尝试将ARCH变量改为上面显示的受支持的仿真,但都无效;如果在LDFLAGS中省略 -V选项,仿真支持不会被列出,但警告/错误是一样的。看起来问题出在链接器调用上,尽管它已安装并确实被调用。
下面是我所使用的编译器的版本信息(32位和64位),但在这次使用的是64位:
armv7a-hardfloat-linux-gnueabi-gcc (Gentoo 15.2.1_p20260214 p5) 15.2.1 20260214
Copyright (C) 2025 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
aarch64-unknown-linux-gnu-gcc (Gentoo 15.2.1_p20260214 p5) 15.2.1 20260214
Copyright (C) 2025 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
解决方案
我认为这是新版本Gentoo工具链变更导致的工具链配置问题。
失败是以下两件事同时发生的结果:
- Gentoo上的GCC 15对
aarch64-unknown-linux-gnu配置默认启用PIE。 - 较新的binutils版本(2.43及更高版本)会将PIE中的
DT_TEXTREL从警告提升为链接时错误。你正在使用的binutils版本是2.46,因此强制执行了这一点。
TF-A BL31是一个EL3固件镜像,直接从固定的物理地址执行。它并不是一个用户态可执行文件,不能被构建为PIE。没有可用来解析运行时relocations的动态加载器,因此对BL31来说PIE构建在本质上就是不正确的。
你有几种选择:
Option 1: Use an older toolchain
最简单的变通方法是使用GCC 14(或更早版本),它对该目标默认不启用PIE。
crossdev --stable -t aarch64-unknown-linux-gnu --gcc 14
Option 2: Explicitly disable PIE
如果你想继续使用GCC 15,请传入禁用PIE生成的标志:
make V=1 -j4 \
CROSS_COMPILE=aarch64-unknown-linux-gnu- \
CFLAGS="-fno-pie -fno-pic" \
LDFLAGS="-no-pie" \
ARCH=aarch64 PLAT=k3 SPD=opteed \
K3_USART=0x6 BL32_BASE=0x80080000 PRELOADED_BL33_BASE=0x82000000 \
TARGET_BOARD=lite all
你可以通过检查详细的构建输出 (V=1) 并在编译/链接命令行中查找 -fPIE、-fpie 或 -pie 来验证PIE是否被注入。
禁用PIE后,DT_TEXTREL 错误应该会消失,BL31应该可以正常链接。