undefined reference to `__aeabi_unwind_cpp_pr1'

led.o:(.ARM.exidx+0x0): undefined reference to `__aeabi_unwind_cpp_pr1’

X210的裸机学习:为了使用C语言来点亮一颗led灯,需要先设置栈指针,用来存放局部变量,然后C语言才能有自己运行的环境,于是就使用汇编写了这样一句:

#define SVC_STACK  0xD0037D80  //初始化栈    

ldr sp, =SVC_STACK    

//以后就可以使用 bl + C函数名 来调用C语言的程序了
bl C_function
b .//跳转到当前,死循环,注意格式为是:b+空格+.

然后是Makefile

led.bin: start.o led.o    
	arm-linux-ld -Ttext 0x0 -o led.elf $^  #链接生成可执行文件    		
	arm-linux-objcopy -O binary led.elf led.bin  #objcopy用来生成可烧录的镜像    
	arm-linux-objdump -D led.elf > led_elf.dis  #objdump反汇编    
	gcc mkv210_image.c -o mkx210 #将image.c预处理编译链接生成可执行文件mkx210    
	./mkx210 led.bin 210.bin   #main 函数传参用来加工sd卡烧录时的校验和    
%.o : %.S #汇编生成.o文件    
	arm-linux-gcc -o $@ $< -c
%.o : %.c #预处理 编译 汇编生成.o 文件   
	 arm-linux-gcc -o $@ $< -c 
clean:    
rm *.o *.elf *.bin *.dis mkx210 -f
.PHONY: clean    

但是make的时候却出现了错误
在这里插入图片描述

原因如下:

我曾在深入理解gcc这篇博客里记录过使用 gcc -v test.o -o test 查看链接时的详细信息
也就是这个样子滴
在这里插入图片描述

crt1.o、crti.o、crtbegin.o、crtend.o、crtn.o是gcc加入的系统标准启动文件,
对于一般应用程序,这些启动是必需的。这就是问题所在了,在写C语言的应用程序的时候,我们又没有配置过栈,没有,那么C语言的应用程序运行的还很完美

显然正是系统标准启动文件帮我们配置了栈

但是我们不需要了,我们写的裸机程序中
#define SVC_STACK 0xD0037D80 //初始化栈
ldr sp, =SVC_STACK

就是在配置栈指针,所以已经不需要系统标准启动文件再来配置了,多次配置就乱套了

解决办法

Makefile 中加上 -nostdlib 选项禁止链接器链接标准库文件即可
就像这样
在这里插入图片描述

我之前给arm-none-linux-gnueabi-gcc 创建过符号链接(软连接)
ln -s arm-none-linux-gnueabi-gcc arm-linux-gcc
并在环境变量里做了声明,所以我Makefile中是 arm-linux-gcc
那么你们就应该是这样
在这里插入图片描述
这样就可以解决了

猜你喜欢

转载自blog.csdn.net/qq_28816873/article/details/104238585