天天看點

uboot中編譯器EABI問題相關說明

在用較新的編譯器編譯舊版uboot,例如uboot1.1.6時,會出現 【undefined reference to `raise'】這種問題,網上大部分的解決方法都是将相關cpu中的config.mk檔案内的編譯選項進行修改

提前說明一點,uboot和linux核心的編譯中arm-linux-gcc的版本很重要

下面的這些代碼中 += 為makefile的文法,意思是為前面的變量添在原有定義的基礎上,再加上後面的定義

PLATFORM_CPPFLAGS += -march=armv4	PLATFORM_CPPFLAGS += 	

PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8 \
	-msoft-float
PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8

PLATFORM_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`) -lgcc
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
           

上述代碼的作用都是為了在編譯的過程中為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,用TQ2440CD光牒裡的crosstool(gcc-3.4.5-glibc-2.3.6)就可以避免EABI的問題了

下載下傳後解壓,放到系統裡的某個位置就可以用了。然後在/etc/profile裡添加編譯器的路徑,最後在終端中source /etc/profile儲存變量即可

本想上傳到網盤,無奈校園網一沒流量二沒速度,有需要同學還是自己上網找找吧,這個crosstool交叉編譯工具在TQ2440CD光牒的EABI-4.3.3_EmbedSky_20091210.tar.bz2這個檔案夾的opt目錄下