Buildroot構建指南——工具鏈


Linux系統的交叉編譯工具鏈用來將源代碼變成bin文件或者庫文件的一個軟件。一般大家默認工具鏈等於gcc或者arm-linux-gcc,但是實際上,gcc只是工具鏈的編譯器部分,不是全部,制作一個工具鏈的原材料,除了gcc,還需要linux內核,libc庫等一系列的軟件包。所謂萬事開頭難,如何在Buildroot中使用自己的交叉編譯工具鏈則是第一道難關。

Buildroot支持從零開始用原材料軟件包自動構造工具鏈,也支持直接使用第三方制作好的工具鏈。

toolchain-buildroot 從零開始自動制作工具鏈

在make menuconfig –> Toolchain –>Toolchain type中,有2個選項,選擇buildroot toolchain則是使用buildroot默認的自動化腳本從零開始制作交叉編譯工具鏈,如果是選擇externaltoolchain 則是使用外部制作好的工具鏈。

Figure 1  toolchain type 選項

在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 制作交叉工具鏈的原材料

工具鏈主要的原材料包括:gcc,、libc庫,、linux內核頭文件、binutils以及一系列自動構建打包工具如m4、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選項

toolchain-external 使用第三方現成工具鏈

這節用友善的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的工具鏈了。

小結

整體而言,從零制作一個工具鏈,對嵌入式的知識掌握還是需要深入的掌握,另外,工具鏈對整個系統代碼的穩定性有着極大的影響,所以直接用自動制作的工具鏈,一定要經過嚴格的壓力測試,否則容易出現各種隱患。

因而,采用第三方制作好的,有專門公司維護的工具鏈,應該是一個更為有效的開發方式。

 

原文鏈接:http://blog.csdn.net/zhou_chenz/article/details/52346134


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM