如何为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完成链接,确保标准库被正确引入:
- 编译阶段:
arm-none-eabi-gcc -c test.c -o test.o -mcpu=cortex-m4 -Wall -Os -fpic -fpie
- 链接阶段:
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
相关产品推荐
相关产品推荐

