由于需要在arm上進行應用的開發(fā),需要搭建arm的編譯環(huán)境馍盟。環(huán)境的搭建有兩種方式:
- 交叉編譯環(huán)境
- arm的開發(fā)環(huán)境
其中交叉編譯環(huán)境包括以下幾種:
- Windows下使用Visual Studio搭建開發(fā)環(huán)境
- Linux下使用GCC搭建開發(fā)環(huán)境
由于Linux環(huán)境搭建起來較為方便落君,推薦使用Linux環(huán)境進行開發(fā)穿香。Visual Studio開發(fā)起來比較方便,IDE做的比較好绎速,但是還是選擇Linux + Makefile的方式更加方便皮获。
Linux環(huán)境的搭建
所謂的環(huán)境搭建,就是安裝一系列編譯與debug的工具纹冤,這里安裝的工具是am-linux-gcc洒宝。
- gcc installation
sudo apt-get install gcc-arm-linux-gnueabihf
- g++ installation
sudo apt-get install g++-arm-linux-gnueabihf
- gcc/g++ remove
sudo apt-get remove gcc-arm-linux-gnueabihf
sudo apt-get remove g++-arm-linux-gnueabihf
工具包名字解釋
gcc是面向于x86-64的編譯工具,可以編譯SSE,AVX等指令集萌京。面向的硬件是桌面級的CPU.而gcc-arm-linux是運行與桌面級的CPU上的軟件雁歌,生成的可執(zhí)行文件是運行在arm的文件。
什么是abi和eabi
- ABI: 二進制應用程序接口(Application Binary Interface (ABI) for the ARM Architecture)
在計算機中知残,應用二進制接口描述了應用程序(或者其他類型)和操作系統(tǒng)之間或其他應用程序的低級接口. - ABI涵蓋了各種細節(jié)靠瞎,如:
- 數(shù)據(jù)類型的大小、布局和對齊;
- 調用約定(控制著函數(shù)的參數(shù)如何傳送以及如何接受返回值)橡庞,例如较坛,是所有的參數(shù)都通過棧傳遞印蔗,還是部分參數(shù)通過寄存器傳遞扒最;哪個寄存器用于哪個函數(shù)參數(shù);通過棧傳遞的第一個函數(shù)參數(shù)是最先push到棧上還是最后华嘹;
- 系統(tǒng)調用的編碼和一個應用如何向操作系統(tǒng)進行系統(tǒng)調用吧趣;
- 以及在一個完整的操作系統(tǒng)ABI中,目標文件的二進制格式、程序庫等等强挫。
一個完整的ABI岔霸,像Intel二進制兼容標準 (iBCS) ,允許支持它的操作系統(tǒng)上的程序不經(jīng)修改在其他支持此ABI的操作體統(tǒng)上運行俯渤。
ABI不同于應用程序接口(API)呆细,API定義了源代碼和庫之間的接口,因此同樣的代碼可以在支持這個API的任何系統(tǒng)中編譯八匠,ABI允許編譯好的目標代碼在使用兼容ABI的系統(tǒng)中無需改動就能運行絮爷。
- EABI:嵌入式ABI
- 嵌入式應用二進制接口指定了文件格式、數(shù)據(jù)類型梨树、寄存器使用坑夯、堆積組織優(yōu)化和在一個嵌入式軟件中的參數(shù)的標準約定。
- 開發(fā)者使用自己的匯編語言也可以使用EABI作為與兼容的編譯器生成的匯編語言的接口抡四。
- 支持EABI的編譯器創(chuàng)建的目標文件可以和使用類似編譯器產(chǎn)生的代碼兼容柜蜈,這樣允許開發(fā)者鏈接一個由不同編譯器產(chǎn)生的庫。
EABI與關于通用計算機的ABI的主要區(qū)別是應用程序代碼中允許使用特權指令指巡,不需要動態(tài)鏈接(有時是禁止的)淑履,和更緊湊的堆棧幀組織用來節(jié)省內存。廣泛使用EABI的有Power PC和ARM.
gnueabi相關的兩個交叉編譯器: gnueabi和gnueabihf
在debian源里這兩個交叉編譯器的定義如下:
- gcc-arm-linux-gnueabi – The GNU C compiler for armel architecture
- gcc-arm-linux-gnueabihf – The GNU C compiler for armhf architecture
可見這兩個交叉編譯器適用于armel和armhf兩個不同的架構, armel和armhf這兩種架構在對待浮點運算采取了不同的策略(有fpu的arm才能支持這兩種浮點運算策略)
其實這兩個交叉編譯器只不過是gcc的選項-mfloat-abi的默認值不同. gcc的選項-mfloat-abi有三種值soft,softfp,hard(其中后兩者都要求arm里有fpu浮點運算單元,soft與后兩者是兼容的厌处,但softfp和hard兩種模式互不兼容):
- soft : 不用fpu進行浮點計算鳖谈,即使有fpu浮點運算單元也不用,而是使用軟件模式。
- softfp : armel架構(對應的編譯器為gcc-arm-linux-gnueabi)采用的默認值阔涉,用fpu計算缆娃,但是傳參數(shù)用普通寄存器傳,這樣中斷的時候瑰排,只需要保存普通寄存器贯要,中斷負荷小,但是參數(shù)需要轉換成浮點的再計算椭住。
- hard : armhf架構(對應的編譯器gcc-arm-linux-gnueabihf)采用的默認值崇渗,用fpu計算,傳參數(shù)也用fpu中的浮點寄存器傳京郑,省去了轉換, 性能最好宅广,但是中斷負荷高。
硬浮點Hard-float
編譯器將代碼直接編譯成發(fā)射給硬件浮點協(xié)處理器(浮點運算單元FPU)去執(zhí)行些举。FPU通常有一套額外的寄存器來完成浮點參數(shù)傳遞和運算跟狱。
使用實際的硬件浮點運算單元FPU當然會帶來性能的提升。因為往往一個浮點的函數(shù)調用需要幾個或者幾十個時鐘周期户魏。
軟浮點 Soft-float
編譯器把浮點運算轉換成浮點運算的函數(shù)調用和庫函數(shù)調用驶臊,沒有FPU的指令調用挪挤,也沒有浮點寄存器的參數(shù)傳遞。浮點參數(shù)的傳遞也是通過ARM寄存器或者堆棧完成关翎。
現(xiàn)在的Linux系統(tǒng)默認編譯選擇使用hard-float扛门,即使系統(tǒng)沒有任何浮點處理器單元,這就會產(chǎn)生非法指令和異常纵寝。因而一般的系統(tǒng)鏡像都采用軟浮點以兼容沒有VFP的處理器论寨。
armel ABI和armhf ABI
在armel中,關于浮點數(shù)計算的約定有三種爽茴。以gcc為例政基,對應的-mfloat-abi參數(shù)值有三個:soft,softfp,hard。
- soft是指所有浮點運算全部在軟件層實現(xiàn)闹啦,效率當然不高沮明,會存在不必要的浮點到整數(shù)、整數(shù)到浮點的轉換窍奋,只適合于早期沒有浮點計算單元的ARM處理器荐健;
- softfp是目前armel的默認設置,它將浮點計算交給FPU處理琳袄,但函數(shù)參數(shù)的傳遞使用通用的整型寄存器而不是FPU寄存器江场;
- hard則使用FPU浮點寄存器將函數(shù)參數(shù)傳遞給FPU處理。
需要注意的是窖逗,在兼容性上址否,soft與后兩者是兼容的,但softfp和hard兩種模式不兼容碎紊。
- 默認情況下佑附,armel使用softfp,因此將hard模式的armel單獨作為一個abi仗考,稱之為armhf音同。
而使用hard模式,在每次浮點相關函數(shù)調用時秃嗜,平均能節(jié)省20個CPU周期权均。對ARM這樣每個周期都很重要的體系結構來說,這樣的提升無疑是巨大的锅锨。- 在完全不改變源碼和配置的情況下叽赊,在一些應用程序上,使用armhf能得到20%——25%的性能提升必搞。對一些嚴重依賴于浮點運算的程序必指,更是可以達到300%的性能提升。