這篇文章對最近遇到上的
ARM上浮點運算的問題做一個總結。
首先,我們先看一下ARM處理器是如何處理浮點運算的。交叉編譯器在編譯的時候,對於浮點運行會預
設硬浮點運算FPA(Float Point Architecture),而沒有FPA的CPU,比如SAMSUNG
S3C2410/S3C2440,會使用FPE(Float Point Emulation
即軟浮點),這樣在速度上就會遇到極大的限制。也就是說如果有浮點副處理器則交給它去做,如果沒有則會產生一個陷阱(trap,處理器響應異常的機制),
而我們事先準備好針對浮點指令的設陷處理常式就可以通過軟體來類比浮點運算指令。
然後,我們
解釋一下OABI和EABI這兩個概念。
/********************************************************************************************/
以下部分轉
載至
http://linux.chinaunix.net/bbs/thread-1143604-1-1.html
。
1。什麼是ABI
ABI,application binary interface
(ABI),應用程式二進位介面。
既然是 介面,那就是某兩種東西之間的溝通橋樑,此處有這些種情況:
A。應用程式 <->
作業系統;
B。應用程式 <-> (應用程式所用到的)庫
C 。應用程式各個組件之間
類似於API的作用
是使得程式的代碼間的相容,ABI目的是使得程式的二進位(層級)的相容。
2。什麼是OABI 和 EABI
OABI中的O,表示
“Old”,“Lagacy”,舊的,過時的,OABI就是舊的/老的ABI。
EABI中的E,表示“Embedded”,是一種新的ABI。
EABI
有時候也叫做GNU EABI。
OABI和EABI都是專門針對ARM的CPU來說的。
3。EABI的好處 / 為何要用EABI
A。支援軟體浮點和硬體實現浮點功
能混用
B。系統調用的效率更高
C。後今後的工具更相容
D。軟體浮點的情況下,EABI的軟體浮點的效率要比OABI高很多。
4。OABI和EABI的區別
兩種ABI在如下方面有區別:
A。調用規則(包括參數如何傳遞及如何獲得返回
值)
B。系統調用的數目以及應用程式應該如何去做系統調用
C。目標檔案的二進位格式,程式庫等
D。結構體中的
填充(padding/packing)和對齊。
E。
OABI:
* ABI flags passed to binutils: -mabi=apcs-gnu -mfpu=fpa
*
gcc -dumpmachine: arm-unknown-linux
* objdump -x for compiled binary:
private flags = 2: [APCS-32] [FPA float format] [has entry
point]
* "file" on compiled
Debian binary:
ELF 32-bit LSB
executable, ARM, version 1 (ARM), for GNU/Linux 2.2.0, dynamically
linked (uses shared libs), for GNU/Linux 2.2.0, stripped
* "readelf -h | grep Flags""
Flags: 0x0
EABI:
* ABI flags passed by gcc to binutils: -mabi=aapcs-linux
-mfloat-abi=soft -meabi=4
* gcc -dumpmachine:
arm-unknown-linux-gnueabi
* objdump -x for compiled binary:
private flags = 4000002: [Version4 EABI] [has entry point]
* "file" on compiled binary (under Debian):
ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux
2.4.17, dynamically linked (uses shared libs), for GNU/Linux 2.4.17,
stripped
* "readelf -h | grep
Flags""
Flags: 0x4000002,
has entry point, Version4 EABI
/********************************************************************************************/
在虛擬機器
中,運行:arm_v5t_le-gcc -dumpmachine,輸出:armv5tl-montavista-linuxeabi;
運行
arm_v5t_le-readelf -h EXEC | grep Flags,(註:EXEC代表用交叉編譯工具編譯的可執行檔名),輸出:
Flags: 0x4000002,
has entry point, Version4 EABI。
上述結果說
明當前使用的montavista的編譯器是符合EABI標準的。
使用EABI(Embedded
Application Binary Interface)則可以對此改善處理,ARM
EABI有許多革新之處,其中最突出的改進就是Float Point Performance,它使用Vector Float
Point(向量浮點),因此可以極大提高涉及到浮點運算的程式。
看到這裡,之前遇到的一個問題終於弄明白
了。之前在Makefile中一直包含一個-mabi=apcs-gnu的參數,而apcs-gnu是OABI的參數,因此將OABI的參數傳給符合
EABI標準的編譯,編譯階段沒有報錯,但在板上運行時,程式中涉及到浮點數的部分出現了許多莫名的問題。比如printf("%s
%f",s,f);這句話輸出的浮點數值並不是傳給printf的參數,而是一個莫名其妙的數字。解決辦法:在Makefile中將
“-mabi=apcs-gnu”去掉,重新編譯運行,成功!
轉載一篇相關文章http://blog.chinaunix.net/u1/38994/showart_2023807.html
。
使用arm- linux-gcc 4.3.2編譯必須啟用核心中的Use the ARM EABI選項
|
|
|
不知道為什麼使用arm-linux-gcc-4.3.2.tgz (with EABI) 86MB
編譯同樣的東西就是出現如下錯誤,感覺可能是busybox 1.14.3的問題,因為使用arm-linux-gcc-4.3.2 編 譯出來的zImage可以使用正常掛在arm-linux-gcc-3.4.1編譯器編譯出來的動態busybox和庫,但是使用arm-linux-gcc-4.3.2.tgz 編譯出來的靜態busybox就是會出現下面的錯誤,開始覺得明顯是應用程式出了問題 .後來發現原來是核心自己的事情,因為arm-linux-gcc-4.3.2.tgz 使 用了EABI方式,所以這就需要核心同樣配置EABI編譯屬性才能支援EABI編譯出來的應用程式busybox[luther.gliethttp]
錯誤原因:沒有選擇Use the ARM EABI to compile the kernel選項
Kernel Features
[ ] Use the ARM EABI to compile the kernel 解決方案:將它尋上之後自動多出下面一行,這樣再次編譯的核心就ok了,嘿嘿:)
[*] Use the ARM EABI to compile the kernel
[*] Allow old ABI binaries to run with this kernel (EXPERIMENTAL) (NEW)
ep93xx-rtc ep93xx-rtc: setting system clock to 1970-01-01 00:01:18 UTC (78)
Freeing init memory: 100K
Kernel panic - not syncing: Attempted to kill init!
Backtrace:
[<c00259c0>] (dump_backtrace+0x0/0x114) from [<c026d674>] (dump_stack+0x18/0x1c)
r7:c5818000 r6:c5817a40 r5:c5817a40 r4:c03291c4
[<c026d65c>] (dump_stack+0x0/0x1c) from [<c026d6c4>] (panic+0x4c/0x120)
[<c026d678>] (panic+0x0/0x120) from [<c00406e0>] (do_exit+0x70/0x58c)
r3:c0313004 r2:c5817a40 r1:c5819d0c r0:c02cbdcb
[<c0040670>] (do_exit+0x0/0x58c) from [<c0040c90>] (do_group_exit+0x94/0xc8)
[<c0040bfc>] (do_group_exit+0x0/0xc8) from [<c004ae40>] (get_signal_to_deliver+0x2ec/0x324)
r7:c5293a74 r6:c5818000 r5:c5819ed4 r4:00000004
[<c004ab54>] (get_signal_to_deliver+0x0/0x324) from [<c0024024>] (do_signal+0x58/0x528)
[<c0023fcc>] (do_signal+0x0/0x528) from [<c0024524>] (do_notify_resume+0x30/0x34)
[<c00244f4>] (do_notify_resume+0x0/0x34) from [<c0021e8c>] (work_pending+0x1c/0x20) |
|