You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Zynq-7000定制RTOS包libgcc链接及Vitis使用咨询

问题背景

我们团队正将原适配旧Intel架构的定制RTOS移植到Zynq-7000 CPU,选用Vitis Unified IDE 2024.2作为开发环境。此前进展顺利,但在移植RTOS专用可加载包(特殊编译的ELF文件)时,遇到无法为armv7-a+vfp架构链接GCC库的问题,例如简单除法需调用__aeabi_uidiv却无法解析。

我们发现Vitis生成的FSBL.elf和our_project.elf中已包含并解析了GCC及标准C函数,但Vitis的构建系统涉及自定义Python文件、配置文件、Lopper和CMakeLists,难以追踪具体链接逻辑,仅通过ProcMon定位到预编译库和Xilinx生成库的目录。

由于包需调用RTOS的函数/全局变量,我们使用-r标记生成可重定位输出,由RTOS加载器完成重定位。以下是包编译的示例Makefile(链接脚本仅包含包识别专用段和入口定义):

CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld
READELF = arm-none-eabi-readelf
OBJDUMP = arm-none-eabi-objdump
PACKAGE = package_another

# https://developer.arm.com/documentation/101754/0623/armclang-Reference/armclang-Command-line-Options
#
# no-common: Avoid multiple definition of global variables in each translation unit
# fPIC: Generate position-independent code
# ffunction-sections & -fdata-sections: Allows linker to optimize section removal 
# nthumb-interwork: Generate code that supports calling between ARM and Thumb instructions
# mpic-data-is-text-relative: Helps the linker to optimize PIC code
CFLAGS = -c \
         -mfpu=vfpv3 \
         -mfloat-abi=hard \
         -mcpu=cortex-a9 \
         -fno-common \
         -fPIC \
         -ffunction-sections \
         -fdata-sections \
         -mthumb-interwork \
         -mpic-data-is-text-relative \
         -O0 \
         -Iinclude 
# r: Generate relocatable output
# gc-sections: Remove unused sections
# build-id=none: Do not generate a build ID
LDFLAGS = -r \
          --gc-sections \
          --build-id=none \
          --no-undefined


all: $(PACKAGE).elf readelf objdump

$(PACKAGE).o: $(PACKAGE).c
    $(CC) $(CFLAGS) $< -o $@

$(PACKAGE).elf: $(PACKAGE).o $(PACKAGE).ld
    $(LD) -T $(PACKAGE).ld $< -o $@ $(LDFLAGS)

readelf:
    $(READELF) -a $(PACKAGE).elf > READELF

objdump:
    $(OBJDUMP) -d $(PACKAGE).elf > OBJDUMP

.PHONY: all clean readelf

clean:
    rm -f $(PACKAGE).o $(PACKAGE).elf b

因使用-r标记,只能通过--whole-archive部分链接libgcc和libc。我们选择了armv7硬浮点版本的libgcc路径:

/mnt/c/Xilinx/Vitis/2024.2/gnu/aarch32/nt/gcc-arm-none-eabi/aarch32-xilinx-eabi/usr/lib/thumb/v7+fp/hard/arm-xilinxmllibv7fphard-eabi/13.3.0/libgcc.a

并将其添加到LDFLAGS中,但存在两个问题:一是引入符号过多(仅需少量),二是仍存在大量未定义符号。

问题1:如何为我们的RTOS包链接最小化版本的libgcc?是否无需与RTOS使用的libgcc一致?

问题2:是否应放弃Vitis IDE?目前仅依赖其构建系统、Lopper工具(XSA变更时重新生成设备树并更新BSP),但后续开发中问题多于便利,且其Python脚本功能有限、文档不足。


解答

针对问题1

最小化链接libgcc的方法

  • 手动提取目标符号对应的目标文件:先用工具定位libgcc.a中包含所需符号的.o文件,再单独提取这些文件链接,而非整库引入。比如找__aeabi_uidiv的命令:
    arm-none-eabi-ar t /path/to/libgcc.a | xargs arm-none-eabi-nm -A | grep __aeabi_uidiv
    
    找到对应的.o文件后,用arm-none-eabi-ar x /path/to/libgcc.a <目标.o文件名>提取,链接时直接用这些.o文件代替整库。
  • 用gcc驱动代替ld直接链接:gcc会自动处理libgcc的依赖筛选,精准引入所需符号。修改Makefile的链接步骤:
    $(PACKAGE).elf: $(PACKAGE).o $(PACKAGE).ld
        $(CC) -r -T $(PACKAGE).ld $< -o $@ $(CFLAGS) -lgcc --build-id=none -Wl,--gc-sections
    
  • 手动实现简单依赖函数:如果仅需除法这类基础功能,可以自己实现对应的函数,完全避开对libgcc符号的依赖。

libgcc版本一致性要求

必须保证RTOS和可加载包使用同版本、同编译选项的libgcc。libgcc的内部符号实现细节会随gcc版本、架构编译选项变化,版本不一致会导致运行时崩溃或行为异常。如果RTOS用的是Vitis自带的gcc 13.3.0,你的包必须用同一版本的libgcc,不能混用。

针对问题2

可以分阶段逐步脱离Vitis IDE,而非直接弃用:

  • 保留Lopper的命令行调用:Lopper工具支持命令行执行,不需要打开IDE。可以写脚本自动调用lopper处理XSA、生成设备树和BSP文件,保留核心的硬件适配能力。
  • 替换构建系统:将自定义Makefile或CMake作为主构建流程,仅在XSA变更时调用Vitis的命令行工具生成BSP,避开IDE复杂且不透明的构建逻辑。
  • 彻底替代的可行性:如果项目不需要Vitis的专属功能(如FPGA+CPU协同调试、特定Xilinx库),可以完全切换到纯GNU工具链+自定义脚本。设备树可用dtc工具配合手动模板生成,BSP部分可参考Vitis生成的代码自行整理必要的硬件初始化逻辑。

总结:若当前IDE带来的麻烦远大于便利,优先保留核心工具的命令行能力,替换构建系统,最后再考虑完全脱离Vitis。


内容的提问来源于stack exchange,提问作者Vladouch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 18:56:03