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

如何为arm-none-eabi-gcc添加生成FDPIC ELF二进制的编译链接参数?

如何为ARM Cortex-M4生成FDPIC格式的二进制文件?

问题背景

现有编译命令:

arm-none-eabi-gcc test.c -o test -mcpu=cortex-m4 -Wall -Os

需要修改参数生成FDPIC二进制文件,目标是在无MMU的STM32上运行的裸Linux内核中(通过initramfs交付)启动程序。

尝试过的方法及问题

1. 拆分编译与链接步骤

执行命令:

arm-none-eabi-gcc -c test.c -o test.o -mcpu=cortex-m4 -Wall -Os
arm-none-eabi-ld test.o --oformat elf32-littlearm-fdpic -pie -o test

出现两个问题:

  • 未自动链接newlib标准库
  • 入口符号缺失警告:
arm-none-eabi-ld: warning: cannot find entry symbol _start; defaulting to 0000000000000074

2. 单步编译传递链接器参数

执行命令:

arm-none-eabi-gcc test.c -o test -mcpu=cortex-m4 -Wall -fpic -fpie -Os -Xlinker "--oformat elf32-littlearm-fdpic"

触发参数识别错误:

/usr/lib/gcc/arm-none-eabi/10.3.1/../../../arm-none-eabi/bin/ld: unrecognized option '--oformat elf32-littlearm-fdpic'
/usr/lib/gcc/arm-none-eabi/10.3.1/../../../arm-none-eabi/bin/ld: use the --help option for usage information
collect2: error: ld returned 1 exit status
make: *** [Makefile:5: all] Error 1

3. 可行但需优化的手动汇编启动方式

当前可运行的Makefile:

all:
    arm-none-eabi-as -mcpu=cortex-m4 init.S -o init.o
    arm-none-eabi-gcc -c -fpic -Os -mcpu=cortex-m4 -fpie -Wall init.c -o init-c.o
    arm-none-eabi-ld init.o init-c.o --oformat elf32-littlearm-fdpic -pie -o init --thumb-entry=_start

配套的init.c:

#define USART1_DR (*((volatile unsigned int *)0x40011004))

int main()
{
    volatile int i;

    USART1_DR = 'A';
    
    for (i = 0; i < 1000000; i++) {
    }

    USART1_DR = 'B';

    while (1) {}
    return 0;
}

init.S启动文件:

.syntax unified
.cpu cortex-m4
.thumb
.global _start

_start:
bl main
b .

说明:该方式可正常运行,但希望通过编译命令直接整合启动流程,无需手动处理汇编文件。


正确解决方案

方案1:单步编译命令(自动链接标准库)

修正参数传递方式,让gcc自动处理标准库和启动逻辑:

arm-none-eabi-gcc test.c -o test -mcpu=cortex-m4 -Wall -Os -fpic -fpie -Xlinker --oformat=elf32-littlearm-fdpic -Xlinker --thumb-entry=_start

参数说明:

  • -fpic/-fpie:生成位置无关代码,满足FDPIC格式要求
  • -Xlinker --oformat=elf32-littlearm-fdpic:用=连接格式名,避免空格导致ld识别错误
  • -Xlinker --thumb-entry=_start:指定Thumb架构下的入口符号,解决入口缺失警告

方案2:拆分编译链接步骤(保留gcc自动链接逻辑)

如果需要拆分步骤,仍用gcc完成链接,确保标准库被正确引入:

  1. 编译阶段:
arm-none-eabi-gcc -c test.c -o test.o -mcpu=cortex-m4 -Wall -Os -fpic -fpie
  1. 链接阶段:
arm-none-eabi-gcc test.o -o test -mcpu=cortex-m4 -fpic -fpie -Xlinker --oformat=elf32-littlearm-fdpic -Xlinker --thumb-entry=_start

关键注意事项

  • 避免直接调用ld链接,否则会跳过gcc的标准库、启动文件自动引入逻辑
  • --oformat参数必须用=连接格式名称,不能用空格分隔
  • Cortex-M4为Thumb架构,必须指定--thumb-entry=_start明确入口模式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 13:53:30