嵌入式ARM板程序的生成器 ---- 交叉編譯器

1. 什麼是編譯器以及交叉編譯器

對於C語言程序,編譯器是啥?通俗的來講編譯器就是把C程序“翻譯”機器語言(二進制)的“翻譯官”,那麼編譯器和交叉編譯器有什麼區別?下面通過一張圖感受一下:

圖1-1 編譯器和交叉編譯器對比圖

通過上面圖我們可以很直觀的看到使用編譯器和交叉編譯器去編譯和執行程序大致流程是大同小異的,只不過交叉編譯器的可執行程序需要從X86(PC)平臺傳送到ARM板平臺提供用戶執行。那麼我們可能存在如下幾個問題:

1. 交叉編譯器編譯出來的可執行程序可以在X86執行嗎?

2. 爲什麼不直接在ARM平臺編譯?

3. ........?(歡迎評論補充)

2. 爲什麼需要交叉編譯器

首先,我們先來分析一個問題:

2.1 爲什麼需要分普通編譯器和交叉編譯器?

這個問題涉及的知識面非常廣,我們首先來看看兩個編譯器面向的平臺,普通編譯器面向的是X86平臺,處理器絕大多數都是Intel的X86架構,注重的是性能,主頻更高,多用於計算機領域;交叉編譯器面向的是ARM平臺,處理器大多數是ARM架構,注重性能和功耗平衡,多用於嵌入式領域。由於兩者使用的指令集是有區別的,所以需要不用的編譯語言,進而分開不同的編譯器。

2.2 交叉編譯器編譯出來的可執行程序可以在X86執行嗎?

上面也說了,X86和ARM的指令集是完全不同的,所以兩者的可執行程序當然不具有兩個平臺運行的兼容性。

如何查看可執行程序屬於的平臺:

使用命令:file <文件名>
圖 2-1 使用GCC編譯程序並查看文件屬性流程圖
圖 2-2 使用arm-linux-gcc編譯程序並查看文件屬性流程圖
圖2-3 在X86平臺執行ARM平臺可執行程序出錯示意圖

2.3 爲什麼不直接在ARM平臺編譯

其實這個是可以實現的,某些ARM平臺的系統具有這樣的編譯環境,但是

因爲通常編譯工具鏈對編譯環境有較高的要求,編譯複雜的程序時,可能需要巨大的存儲空間以及強大的CPU運算能力加快編譯速度。常見的ARM架構平臺資源有限,無論存儲空間還是CPU運算能力,都與PC相去甚遠,特別是對於MCU平臺,安裝編譯器根本無從談起。有了交叉編譯,我們就可以在PC上快速編出譯針對其他架構的可執行程序。

                                                                                                                            ----《野火 i.MX+Linux開發實戰指南》

在此插句話,推薦大家可以去看看正點原子和野火的ARM資料,目前已經開售板子和開放資料,ARM linux入門需要一個指路人,少走很多彎路。博主出生早了,入門學習時沒趕上,現在去薅羊毛。。。。

3. 安裝交叉編譯器

3.1 交叉編譯器介紹

(Ubuntu)安裝交叉編譯器主要有三種方式:

1. 下載 Linaro 製作好的第三方工具鏈(選擇多)

2. 通過apt-get在線安裝(方便快速)

3. 使用crosstool-ng 根據需要自己自作(複雜,不會)

主要介紹第一種:

Linaro 交叉工具鏈下載鏈接

選擇最新(截止2019/11/19)的:7.4-2019.02

圖3-1 交叉工具鏈類型一覽
表格3-1 交叉工具鏈說明表格
名稱 適用的平臺
aarch64-linux-gnu    適合64-bit Armv8 Cortex-A,little-endian(小端)
aarch64_be-linux-gnu 適合64-bit Armv8 Cortex-A,big-endian(大端)
arm-linux-gnueabi 適合32-bit Armv7 Cortex-A,soft-float(軟件浮點),little-endian(小端)
arm-linux-gnueabihf 適合32-bit Armv7 Cortex-A,hard-float(軟件浮點),little-endian(小端)
armeb-linux-gnueabi 適合32-bit Armv7 Cortex-A,soft-float(軟件浮點),big-endian(大端)
armv8l-linux-gnueabihf 適合32-bit Armv8 Cortex-A,soft-float(軟件浮點),little-endian(小端)

接下來我們可以去分析我們的平臺適用哪一種交叉工具鏈:

3.2 分析平臺架構

一般來說,根據使用的處理器就可以得到架構(Armv7 or Armv8),博主使用的是三星的S5P6818處理器,Cortex-A53內核,64位Armv8架構(兼容32位Armv7架構)。

圖3-2 S5P6818芯片官方手冊介紹截圖

但是最穩妥的辦法還是去看看實際的系統信息:

使用命令查看系統屬性:uname -a
圖3-3 uname查看系統信息

可以看到我的系統屬於armv7l架構,也就是選擇:

arm-linux-gnueabi、arm-linux-gnueabihf

兩者隨便選嗎?會發生如下錯誤:

圖3-4 在只有 soft float 環境的平臺運行hard float 出錯示意圖

 

3.3 分析平臺支持的浮點計算方式

那麼怎麼確定系統是soft float還是 hard float 呢?我們可以通過一個巧妙的方法去確定,將ARM板上動態庫文件(例如:/lib/libc.so.6)傳輸到PC上使用readelf查看文件信息(因爲ARM板沒有readelf工具):

圖3-5 使用readelf工具查看文件信息示意圖

可以看到,我的動態庫屬於soft-float類型文件,所以支持hard-float的平臺也得看看動態庫支持的類型。當然,你也可以靜態編譯文件,不是使用動態庫,這樣就可以支持hard-float(前提是硬件支持)。

3.4 下載工具鏈

圖3-6 下載工具鏈一覽圖

我的是64位機,下載第二個,這個網站對於國內來說穩定性不行,爲了方便大家下載,我把資源共享到百度雲上:

工具鏈下載百度雲資料

3.5 解壓、配置和使用工具鏈

  • 將工具鏈壓縮包拷貝到 /usr/local/arm/   目錄下

這個路徑是隨意的,與後面的配置環境變量相關,但是usr(Unix Software Resource)目錄下通常存放各類軟件,工具鏈其實也就是一個軟件。

圖3-7 解壓工具鏈壓縮包流程圖
圖3-8 解壓目錄文件一覽
圖3-9 bin目錄文件一覽

重點關注 bin ,bin下存放的就是可執行程序,也就是我們需要的工具鏈。

include 是標準庫文件的頭文件存放目錄,lib存放一些庫文件。

  • 做軟鏈接(不是必須)

做軟鏈接的目的就相當於 Windows 下創建一個快捷方式。不是必須但是方便使用。 

圖3-10 做軟鏈接流程圖
  • 配置環境變量,方便全局使用

打開家目錄下的 .bashrc 在最後加入配置語句,.bashrc屬於個人用戶配置文件,PATH屬於系統全局的變量,這樣做的可以使工具鏈全局可見(也就是整個操作系統任意位置都可以使用 amr-linux-gcc ),操作如下圖

圖3-11 打開.bashrc配置文件
圖3-12 配置文件圖
  • 使環境變量立即生效(重啓也行),查看工具鏈版本
圖3-13 生效工具鏈,查看版本

4. 說在最後

其實工具鏈的安裝和大多數linux工具的安裝流程都是十分相似的:

下載工具  --->  移動到指定位置  --->  配置環境變量

通過配置工具也是去了解和熟悉操作系統工作原理的有效途徑。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章