在用較新的編譯器編譯舊版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目錄下