i.MX6ULL開發板原始碼交叉編譯器介紹

武漢永珍奧科發表於2021-12-24
前言
文章基於HD-IMX6ULL-MB  系列開發板測試驗證,該開發板由武漢芯路遙科技有限公司與武漢永珍奧科電子有限公司合作推出。此開發板基於 NXP iMX6ULL 系列 Cortex-A7 高效能處理器設計,適用於快速開發一系列具有創新性的產品如人機介面工業 4.0 掃描器、車載終端以及行動式醫療裝置。



i.MX6ULL開發板原始碼交叉編譯器介紹

1.交叉編譯器介紹


1.1. 交叉編譯器


在 X86 架構 Linux 系統下進行 C 程式開發時, 我們使用系統的 gcc 編譯器進行程式碼的編譯, 編譯生成的可執行程式直接在 X86 架構下的 PC 下執行的,這個過程叫做 本地編譯 (Native Compile) 。 而如果該C程式想要編譯出來後放到ARM處理器架構的系統上執行, 則需要在 X86 架構Linux系統下使用支援 ARM 的編譯器編譯, 這個編譯器我們通常稱為 交叉編譯器 (Cross Compiler)。

而在一種平臺上編譯出能在另外一種體系結構完全不同處理器上執行程式的編譯過程,叫做 交叉編譯(Cross Compile)。比如在PC平臺(X86  CPU)上編譯出能執行在以ARM為核心的CPU平臺上的程式,編譯得到的程式在X86 CPU平臺上是不能執行的,必須放到ARM  CPU平臺上才能執行,雖然兩個平臺用的都是Linux系統。

i.MX6ULL開發板原始碼交叉編譯器介紹


交叉編譯工具鏈是一個由編譯器、聯結器和直譯器組成的綜合開發環境,交叉編譯工具鏈主要由binutils、gcc和glibc三個部分組成。有時出於減小 libc 庫大小的考慮,也可以用別的 c 庫來代替 glibc, 例如 uClibc 或 newlib。

之所以幾乎所有的ARM開發板開發都選擇交叉編譯,這是因為這些開發板生產出來後並沒有系統,這 時需要在PC上使用交叉編譯器交叉編譯作業系統原始碼,為它構建一個完整的 Linux 系統。另外,由於CPU處理能力、外存和記憶體儲存空間的大小限制,它們不足以能夠執行 gcc 編譯環境,所以嵌入式開發絕大部分的過程都是交叉編譯。

1.2 常用的交叉編譯器


1.2.1 Codesourcery 交叉編譯器

Codesourcery一直是在做 ARM 目標 GCC 的開發和最佳化,它直接提供 Windows和Linux下的二進位制版本交叉編譯器,不用下載原始碼包一步一步自己編譯,非常方便。它的 ARM GCC 早期在市場上非常優秀,很多公司在作嵌入式產品開發時,都會直接下載使用該公司提供的交叉編譯器。
Codesourcery 推出的產品叫 Sourcery G++ Lite Edition, 其中基於 command-line 的編譯器是免費的, 在官網上可以下載, 而其中包含的 IDE 和 debug 工具是收費的, 當然也有30天試用版本的。後來CodeSourcery 被明導國際(Mentor Graphics)收購, 現在則被西門子(Siemens) 收購了。


1.2.2 Linaro交叉編譯器


除了CodeSourcery外,還有一個組織也提供ARM    Toolchain,它就是Linaro。Linaro是在2010年臺北國際計算機展(COMPUTEX)期間,ARM、Freescale、Samsung  ,ST-Ericsson、德州儀器(TI)與IBM等6家大廠,宣佈合資成立的非贏利Linux基礎架構軟體研發商。

Linaro目標在投入新資源和整合業界的努力,改進與最佳化在ARM-based架構上執行的開放原始碼軟體及 開發工具,將過去必須由系統單晶片(SoC)業者,各自將本身產品與Linux作業系統整合與開發的重複投  資,透過這間合資公司推出開放原始碼的底層軟體工具,解決ARM生態系中,重複投資造成的資源浪     費。

1.2.3 Ubuntu交叉編譯器

Ubuntu之所以能成為嵌入式系統開發的首選Linux發行版本,正是因為它的軟體包線上安裝倉庫中包含 有海量的開發工具/軟體,其中就包括嵌入式系統開發所需的交叉編譯器、dtc等開發工具,這也就是為  什麼幾乎所有主流的半導體廠商在釋出SDK時都推薦使用Ubuntu系統。

在Ubuntu 系統中提供瞭如下四個版本的交叉編譯器軟體包:

  • gcc-arm-linux-gnueabi ---- armel,ARM EABI Little-endian
  • gcc-arm-linux-gnueabihf ---- armhf,ARM Hard Float
  • gcc-arm-none-eabi ---- bare metal, Linux下用於編譯 ARM 架構的裸機系統,使用的是newlib這個嵌入式C庫。
  • gcc-aarch64-linux-gnu ---- arm64,用於編譯64位ARM處理器系統

在上面的軟體包中,gcc-arm-none-eabi 和 gcc-aarch64-linux-gnu 都比較好理解。而 gcc-arm-linux- gnueabi 與 gcc-arm-linux-gnueabihf 有什麼區別呢?這就涉及到 ARM 處理器架構中的浮點運算相關知識了。

出於低功耗、封裝限制等種種原因,以前的一些ARM處理器沒有獨立的硬體浮點運算單元,需要使用軟 件來實現浮點運算。隨著技術發展,現在高階的ARM處理器基本都具備了硬體執行浮點操作的能力。這 樣,新舊兩種架構之間的差異,就產生了兩個不同的嵌入式應用程式二進位制介面(EABI)——軟浮點

i.MX6ULL開發板原始碼交叉編譯器介紹
(SoftFP)與向量浮點(VFP)。但是軟浮點(soft float)和硬浮點(hard  float)之間有向前相容卻沒有向後相容的能力,也就是軟浮點的二進位制介面(EABI)仍然可以用於當前的高階ARM處理器。

在ARM體系架構核心中,有些有浮點運算單元(fpu,floating point  unit),有些沒有。對於沒有fpu核心,是不能使用armel和armhf的。在有fpu的情況下,就可以透過gcc的選項-mfloat-abi來指定使用哪    種,有如下四種值:
1.soft:不用fpu計算,即使有fpu浮點運算單元也不用。
2.armel:(arm eabi little endian)也即softfp,用fpu計算,但是傳引數用普通暫存器傳,這樣中斷的時候,只需要儲存普通暫存器,中斷負荷小,但是引數需要轉換成浮點的再計算。
3.armhf:(arm hard  float)也即hard,用fpu計算,傳引數用fpu中的浮點暫存器傳,省去了轉換效能最好,但是中斷負荷高。
4.arm64:64位的arm預設就是hard float的,因此不需要hf的字尾。

在之前的EABI中,armel(低端ARM硬體)在執行浮點運算之前,浮點引數必須首先透過整數暫存器,   然後傳遞到浮點運算單元。新的EABI   ,也就是armhf,透過直接傳遞引數到浮點暫存器最佳化了浮點運算的呼叫約定。相比我們熟悉的armel,armhf代表了另一種不相容的二進位制標準。在一些社群的支援下,armhf目前已經得到了很大的發展。像Ubuntu,已經計劃在之後的發行版中放棄armel,轉而支援armhf編譯的版本。正如目前依然很火熱的Raspberry  Pi(ARM11),由於ubuntu只支援armv7架構的編譯,Raspberry Pi將不能直接安裝ubuntu系統。而 BB Black(Cortex-A8)和 Cubietruct(Cortex-A7)則同時支援ubuntu的armel與armhf的編譯。

kernel、rootfs和app編譯的時候,指定的必須保持一致才行。使用softfp模式,會存在不必要的浮點到  整數、整數到浮點的轉換。而使用hard模式,在每次浮點相關函式呼叫時,平均能節省20個CPU週期。 對ARM這樣每個週期都很重要的體系結構來說,這樣的提升無疑是巨大的。在完全不改變原始碼和配置的  情況下,在一些應用程式上,雖然armhf比armel硬體要求(確切的是指fpu硬體)高一點,但是armhf   能得到20-25%的效能提升。對一些嚴重依賴於浮點運算的程式,更是可以達到300%的效能提升。

1.3. 交叉編譯測試


接下來我們以大家熟悉的 hello world 程式為例,講解嵌入式交叉編譯過程。

1.3.1 本地編譯執行hello程式


首先,我們使用 vim 編輯器編寫 hello.c 測試程式:

i.MX6ULL開發板原始碼交叉編譯器介紹

我們知道,C程式必須要使用編譯器編譯生成可執行程式,才能執行。接下來我們使用 Linux伺服器上的
gcc 編譯該程式並執行:

i.MX6ULL開發板原始碼交叉編譯器介紹


我們可以使用 file 命令檢視 hello 程式的相關資訊,由此可知該程式應該在X86-64位的系統上執行:

i.MX6ULL開發板原始碼交叉編譯器介紹



我們將該程式下載到開發板上執行試試看,這時系統會提示可執行檔案格式出錯,不能正常執行。


i.MX6ULL開發板原始碼交叉編譯器介紹


1.3.2 交叉編譯執行hello程式


我們知道C程式具有可移植性,使用PC上的編譯器編譯生成的程式應該在PC上執行,而不能在其他處理 器架構上執行,那怎樣讓 hello.c  程式在ARM開發板上執行呢?這裡就需要使用ARM的交叉編譯器來對該程式進行交叉編譯,這樣編譯輸出的可執行程式就能在ARM開發板上執行了。

因為我們的 i.MX6ULL 處理器帶有硬體浮點FPU,所以這裡我們選擇安裝硬浮點交叉編譯器:


i.MX6ULL開發板原始碼交叉編譯器介紹


接下來,我們使用 ARM 的交叉編譯器編譯該 hello.c 程式,並嘗試在 X86-64位 Linux伺服器上執行,我們會發現 Linux 伺服器上預設並不能執行該程式:

i.MX6ULL開發板原始碼交叉編譯器介紹


接下來我們使用 file 命令檢視該程式的相關資訊,由此可知該程式應該在ARM處理器系統上執行:

i.MX6ULL開發板原始碼交叉編譯器介紹


我們將該程式下載到開發板上則能正常執行了。

i.MX6ULL開發板原始碼交叉編譯器介紹

由此可見:
C程式如果想在PC上執行,則應該用PC的編譯器來編譯;而該程式想要在ARM開發板上執行,則必 須用ARM的交叉編譯器對原始碼重新進行交叉編譯;
C程式具有可移植性是指,C程式原始碼不用作任何的修改,使用不同的編譯器編譯生成的可執行程 序可以在不同的處理器架構平臺上執行;

版權宣告

本文件所有內容文字資料由凌雲實驗室郭工編著,主要用於凌雲嵌入式Linux教學內部使用,版權歸屬 作者個人所有。任何媒體、網站、或個人未經本人協議授權不得轉載、連結、轉帖或以其他方式複製釋出/發表。已經授權的媒體、網站,在下載使用時必須註明來源,違者本人將依法追究責任。
Copyright (C)2021 凌雲物網智科實驗室·郭工
Author: GuoWenxue guowenxue@gmail.com


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70009145/viewspace-2849211/,如需轉載,請註明出處,否則將追究法律責任。

相關文章