uboot中编译器EABI问题相关说明

来源:互联网 发布:sql注入漏洞如何修复 编辑:程序博客网 时间:2024/06/01 22:19

在用较新的编译器编译旧版uboot,例如uboot1.1.6时,会出现 【undefined reference to `raise'】这种问题,网上大部分的解决方法都是将相关cpu中的config.mk文件内的编译选项进行修改

提前说明一点,uboot和linux内核的编译中arm-linux-gcc的版本很重要

下面的这些代码中 += 为makefile的语法,意思是为前面的变量添在原有定义的基础上,再加上后面的定义

PLATFORM_CPPFLAGS += -march=armv4PLATFORM_CPPFLAGS += PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8 \-msoft-floatPLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32)PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))PLATFORM_RELFLAGS +=$(call cc-option,$(call cc-option,)PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgccPLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc \-lc -L/home/fish/CodeSourcery/Sourcery_G++_Lite/arm-none-linux-gnueabi/libc/armv4t/usr/lib

上述代码的作用都是为了在编译的过程中为arm-linux-gcc添加编译选项,一般用于代码优化——具体参考GCC中文手册

-fno-strict-aliasing

如果使用-fno-strict-aliasing参数编译,编译器认为num和array有可能指向同一片区域。由于编译器认为给array[i]赋值有可能会改变num[0],所以循环内部num[0]的值每次都是从内存里取的。

-fno-common 
即使未初始化的全局变量也分配在目标文件的bss段,而不是把它们当做普通块(common block)建立.这样的 结果是,如果在两个不同的编译结果中声明了同一个变量(没使用extern ),连接它们时会产生错误. 这个选项可能有用的唯一情况是,你希望确认程序能在其他系统上运行,而其他系统总是这么做. 

-ffixed-reg 

把名为reg的寄存器按固定寄存器看待(fixed register);生成的目标码不应该引用它(除了或许 用作栈指针,帧指针,或其他固定的角色). reg必须是寄存器的名字.寄存器名字取决于机器,用机器描述宏文件的REGISTER_NAMES宏 定义. 这个选项没有否定格式,因为它列出三路选择. 

-msoft-float
输出包含浮点库调用的目标代码

call cc-option

用于检查编译器是否支持某种编译选项,在scripts/Kbuild.include定义

-mapcs-32
产生使用32比特程序计数器的处理器代码,遵从APCS 32比特选项的函数调用标准。此开关替代了编译器早期版本中的“-m6”

-mabi=apcs-gnu

apcs-gnu是OABI的 参数,因此将OABI的参数传给符合EABI标准的编译

这个参考这里 http://www.cnblogs.com/leaven/archive/2010/11/16/1878291.html

这篇文章中有这么一段

【编译阶段没有报错,但在板上运行时,程序中涉及到浮点数的部分出现了许多莫名的问题。比如 printf("%s %f",s,f);这句话输出的浮点数值并不是传给printf的参数,而是一个莫名其妙的数字。解决办法:在Makefile中将 “-mabi=apcs-gnu”去掉,重新编译运行,成功!】

-mshort-load-bytes-malignment-traps

这两项的含义相同,只不过前者在低版本GCC中使用,高版本GCC中用后者

mshort认为int为16位宽度,相当于short int


我在编译uboot1.1.6源码时,使用的是gcc version 4.2.3 (Sourcery G++ Lite 2008q1-126)  在做到添加NAND_FLASH那里时报了这个错误:

../lib/gcc/arm-none-linux-gnueabi/4.2.3/libgcc.a(_dvmd_lnx.o): In function `__aeabi_ldiv0':
(.text+0x8): undefined reference to `raise'

参照网上乱七八糟的改,什么去掉-march=armv4这种,代码虽然能编译成功,但是根本不能运行,所以众位网友还是慎重一些,别改乱了弄不回去


我将根目录Makefile中PLATFORM_LIBS改成了

PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc \
-lc -L/home/fish/CodeSourcery/Sourcery_G++_Lite/arm-none-linux-gnueabi/libc/armv4t/usr/lib

将cpu/arm920t/config.mk中的PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)改成了PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32)

修改上述两项之后通过了编译,但是还没测,USB转串口被人拿走了……




试来试去,还是换个低版本的编译器吧。我用的uboot是1.1.6,用TQ2440光盘里的crosstool(gcc-3.4.5-glibc-2.3.6)就可以避免EABI的问题了

下载后解压,放到系统里的某个位置就可以用了。然后在/etc/profile里添加编译器的路径,最后在终端中source /etc/profile保存变量即可

本想上传到网盘,无奈校园网一没流量二没速度,有需要同学还是自己上网找找吧,这个crosstool交叉编译工具在TQ2440光盘的EABI-4.3.3_EmbedSky_20091210.tar.bz2这个文件夹的opt目录下


原创粉丝点击