本文轉載自:http://blog.csdn.net/zhou_chenz/article/details/52346134linux
Linux系統的交叉編譯工具鏈用來將源代碼變成bin文件或者庫文件的一個軟件。通常你們默認工具鏈等於gcc或者arm-linux-gcc,可是實際上,gcc只是工具鏈的編譯器部分,不是所有,製做一個工具鏈的原材料,除了gcc,還須要linux內核,libc庫等一系列的軟件包。所謂萬事開頭難,如何在Buildroot中使用本身的交叉編譯工具鏈則是第一道難關。git
Buildroot支持從零開始用原材料軟件包自動構造工具鏈,也支持直接使用第三方製做好的工具鏈。架構
在make menuconfig –> Toolchain –>Toolchain type中,有2個選項,選擇buildroot toolchain則是使用buildroot默認的自動化腳本從零開始製做交叉編譯工具鏈,若是是選擇externaltoolchain 則是使用外部製做好的工具鏈。app
Figure 1 toolchain type 選項ionic
在mini2440_defconfig的配置文件中,咱們能夠看到,它並無toochain相關的選項,只是在cpu指令集部分選擇了ARM920T ,這種狀況它會採用buildroot-toolchain也就是buildroot默認的自動化腳本,從零開始製做工具鏈。實際上,你只要make toolchain而後等待幾分鐘,Buildroot就會將製做好的全新工具鏈放到output/host/目錄下了。工具
Figure 2 mini2440_defconfig配置部分截圖性能
整個工具鏈自動化製做過程能夠參考toolchain/ 目錄下的toolchain-buildroot/ 、toolchain.mk、helpers.mk、toolchain-wrapper.mk等幾個腳本,我就不詳細說了。可是有幾個關鍵點我仍是強在下面列一下。總之製做過程仍是很複雜的,因此若是是初學者,用手工方法從零開始作交叉編譯工具鏈,將是多大的挑戰。測試
a). 從圖3中咱們能夠看到製做交叉工具鏈大概須要的原材料軟件包網站
Figure3 製做交叉工具鏈的原材料ui
工具鏈主要的原材料包括:gcc,、libc庫,、linux內核頭文件、binutils以及一系列自動構建打包工具如m四、gmp、mpc等。
另外要強調的是,從工具鏈的原材料能夠知道爲何Linux內核、驅動以及應用軟件要用同一個工具鏈編譯,爲何內核版本要適配它的工具鏈。這是由於工具鏈自己的製做依賴於特定版本的Linux內核和libc庫。
b). 從圖1的makemenuconfig –> Toolchain這一系列選項能夠看到,製做工具鏈還能夠選擇libc庫(uclibc仍是glibc,本身添加Android特有的Bionic libc),不一樣的libc性能,size,效率,穩定性以及GPL協議支持上有着必定的差別,須要使用者謹慎選擇和測試。mini2440直接採用buildroot提供的默認的uclibc,不保證其穩定性和bug。
另外,toolchain後面還有Linux內核版本以及MMUsupport以及gcc版本的選擇,可見若是須要定製特定的Linux內核(好比不帶MMU的實時版),除了移植內核以外,還須要特別爲其定製工具鏈。
c). make menuconfig –> Target option 中的選項也是與交叉工具鏈密切相關的。
其中芯片的CPU的大小端,是否編譯成elf格式,指令集,ABI的類型(EABI是Embeded ABI的意思,EABIHF是採用硬浮點的ABI),以及軟硬浮點特性(軟浮點不會有編譯兼容性問題,可是在支持硬浮點的高級嵌入式芯片,採用軟浮點配置,不少性能會發揮不佳,可是ARM9這種低端平臺用軟浮點應該OK)等等選項,都是應該考慮的點。
Figure4 與交叉工具鏈相關的target option選項
這節用友善的Tiny4412開發板官方提供的工具鏈爲例,介紹如何將外部第三方工具鏈移植到到Buildroot的編譯環境。Tiny4412開發板用的SOC芯片的基於ARM-Cortex-A9內核的三星Exyons-4412 真四核SOC芯片,曾經是三星旗艦手機Galaxy-S3的主打SOC。
從友善官方提供的交叉編譯工具鏈的包命名來看,工具鏈使用的gcc版本是4.5.1,有vfp則說明工具鏈支持應付點編譯。V6應該是指令集是ARMV6,可是ARM-V6其實是ARM11的指令集,Cortex-A9的應該是ArmV7纔對, 這裏應該是命名出錯了,算是一個小漏洞吧。
Figure5 友善官方提供的tiny4412交叉編譯工具鏈
移植步驟以下:
1. 爲了避免產生命名誤導,咱們將工具鏈的壓縮包中4.5.1/* 目錄下的因此內容拷貝出來,放到一個叫toolchain-tiny4412從新壓縮成名字爲arm-linux-gcc-4.5.1-tiny4412.tar.bz2的壓縮包,將其cp到/mnt/sdb/3rd-pkg目錄下,細心的朋友已經發現,根據前面一篇Buildroot快速入門的內容,這個文件夾是我保存第三方軟件包的專門文件夾,待會Buildroot會用file的方法從該文件夾中把工具鏈cp到buildroot/dl/目錄下的。
Figure6 保存在/mnt/sdb/3rd-pkg 目錄下的工具鏈壓縮包
2. 在make menuconfig –> Toolchain –>Toolchain type中選中external toolchain,下面的Toolchain欄中的arm-linux-gcc-4.5.1for tiny4412選項,實際上本來是沒有的,是我本身加上去的。
Figure7 Toolchain的選擇
3. 那麼如何把本身的工具鏈加上去呢?cd buildroot/toolchain/toolchain-external/文件夾,根據前一篇文章快速上手的經驗,要加本身的工具鏈,確定是該配置,再改mk文件啦!
在該目錄的Config.in文件的108行,有一個現成的第三方ARM cortex-A9 第三方交叉工具鏈的配置代碼。
Figure8 buildroot/toolchain/toolchain-external/Config.in中的ARM Cortex-A9現成參考配置
咱們能夠參考模仿這段代碼,稍微修改,在這段代碼後面加入咱們本身的配置代碼:
注意,命名很重要,變量名必定是BR2_TOOLCHAIN_EXTERNAL_開頭,後面加上本身的工具鏈名。
Figure9 Config.in中參考修改的tiny4412工具鏈配置代碼
在個人修改中,出來提示字符串和help部分的相關注釋和提示文字,主要是把主機gcc版本的最低要求下降到4.5,再去掉了內核頭文件最低版本限制(這裏實際上是友善官方的疏忽,友善在製做工具鏈的時候,採用的Linux內核頭文件版本很低,和編譯的內核版本不匹配,致使頭文件版本檢查會報錯,於是我去掉了最低版本的限制,這也是潛在漏洞之一吧)。
4. 配置交叉工具鏈前綴名。在Config.in的690行左右,爲剛纔添加的BR2_TOOLCHAIN_EXTERNAL_TINY4412_ARM選擇工具鏈前綴名。
前綴名的格式組成是這樣的:目標cpu-廠商-操做系統-庫和abi格式,咱們參考以前模仿的配置,選擇arm-nonelinux-gnueabi,
實際上,友善官方給的工具鏈就是以arm-nonelinux-gnueabi做爲前綴命名的。
Figure10 工具鏈前綴名配置
Figure11 tiny4412官方的工具鏈命名
5. 修改toolchain-external.mk 文件,加入本身配置。在296行,仿照前面一個工具鏈的變量配置,爲BR2_TOOLCHAIN_EXTERNAL_TINY4412_ARM的配置增長下載地址和壓縮包的名字,壓縮包名字在第一步已經作好。至於下載地址,直接抄過來就好了,友善提供的定製化工具鏈,網上下載不到的。
Figure12 爲toolchain-external.mk 加入tiny4412工具鏈的配置
事實上,打開那個地址,咱們能夠看到由sourcery官方維護的不少現成製做好的工具鏈,因此嘛直接拿來用就行了,本身從零製做工具鏈多麻煩啊!固然這些工具鏈的穩定性仍是須要本身測試一番。
Figure13 sourcery網上可下載的現成工具鏈
6. 在menuconfig中設置下載的鏡像地址。這個和前一篇文章同樣,將本地保存工具鏈的地址,按照格式,設置爲file的鏡像地址。實際上,Buildroot的下載腳本,默認的規定是優先去本地的file鏡像地址找軟件包,找不到以後,纔會走git或者網站下載等其它方法。固然網上確定是下載不到的,可是先從本地找到就OK,這也是第一步爲何要保存工具鏈壓縮包到該地址的緣由。
關於Buildroot下載軟件包的順序,能夠參考package/pkg-download.mk的腳本,在214行能夠看到,只有在本地file路徑找不到了,纔會採用配置的(PKG)_SITE_METHOD方法去獲取軟件包。
Figure14 工具鏈的下載鏡像地址
Figure15 Buildroot自動下載腳本的下載過程
7. menuconfig中的幾項配置。修改完配置腳本和編譯構建mk腳本後,還得在menuconfig中把修改的東西配置進去。
在target Option的配置中,注意上一節提到的幾點。可是這裏有幾個新的選項須要注意
a). CPU架構選擇的是Cortex-A9
b) vfp友善官方給的工具鏈是支持的,因此這裏能夠打開,這樣就能支持硬浮點了
c) NEON SIMD是CPU支持的高性能多媒體引擎的功能,這是4412這種級別的多媒體處理器的殺手級功能,可是咱們如今並不瞭解它的特性,也不知道友善的工具鏈在製做的有沒有把該功能加上去,於是暫時不打開。可是專業的工程師要去了解這項功能,以便發揮SOC和CPU的潛能。
d). VFP硬浮點的版本,這一項因爲友善的資料不明確,暫時選VFPv3-D16版本,根聽說明,Coretex-A9對這個版本都會支持的。
e). ABI的問題,根據圖11的內容,友善的工具鏈應該只是用了EABI來作的,沒有用EABIhf。這幾項是什麼意思呢?浮點選項其實有軟浮點、硬浮點EABI(softfp)和硬浮點EABIhf三個。
軟浮點就是用軟件模擬浮點運算
硬浮點EABI就是用浮點指令,可是爲了兼容舊版本的軟浮點編譯出來的庫仍是用整數寄存器傳遞浮點數,這樣犧牲了一些效率,可是在工具鏈中存在舊的軟浮點庫時,是能夠兼容並不會出現編譯錯誤的。
硬浮點EABIhf則是使用純粹的硬浮點指令和浮點寄存器來計算浮點數,這樣效率會更高,可是再也不兼容工具鏈中舊版的軟浮點下編譯出來的庫,若是不從新制做硬浮點EABIhf的工具鏈,可能會出現編譯問題。
EABIhf須要知道整個工具鏈的庫的兼容特性,目前看起來友善官方工具鏈不支持這個選項,其工具鏈命名也是EABI,可是有支持vfp,於是咱們選擇硬浮點EABI的配置。具體要如何支持EABIhf,能夠搜其它相關文章,這個可能須要從新制做整個工具鏈。
以上這些選項實際上都是編譯toolchain-wrapper傳遞的,toolchain-wrapper是一箇中間層,負責編譯時,傳遞某些特定選項給工具鏈,以上這些選項肯定後,都會被toolchain-wrapper以參數的時候在編譯時傳遞給交叉工具鏈的。
Figure 16 menuconfig -->target option的配置
Figure 17 menuconfig -->toolchain的配置
在加入了tiny4412的配置後,最後在toolchani中選擇本身的工具鏈,選上MMU功能,而後用pipe選項進行編譯加速。
最後,make toolchain ,你就能夠看到Buildroot系統如何構建出tiny4412的工具鏈了。
總體而言,從零製做一個工具鏈,對嵌入式的知識掌握仍是須要深刻的掌握,另外,工具鏈對整個系統代碼的穩定性有着極大的影響,因此直接用自動製做的工具鏈,必定要通過嚴格的壓力測試,不然容易出現各類隱患。
於是,採用第三方製做好的,有專門公司維護的工具鏈,應該是一個更爲有效的開發方式。