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
那么你们就应该是这样
这样就可以解决了