---
# System prepended metadata

title: 嵌入式 Linux 啟動組件

---

**示範機板: beaglebone black
組建環境 : Ubuntu 20.04 LTS**
# Toolchain 工具鏈

工具鏈是嵌入式 linux 中首要的原件，所有預計於裝置上執行的程式碼，都需要使用工具鏈來編譯。好的工具鏈要能根據處理器的規格，使用最適合的指令集來發揮硬體的效能。在開發過程中應該要使用同一套工具鏈，在開發過程中經常性的更換 compiler 或 函式庫將會導致不可預期的結果。

開始前先安裝後續會用到的工具

```shell 
 sudo apt-get install autoconf automake bison \
 bzip2 cmake flex g++ gawk gcc gettext git gperf help2man \
 libncurses5-dev libstdc++6 libtool libtool-bin make patch \ 
 python3-dev rsync texinfo unzip wget xz-utils
```

### 甚麼是 toolchain ?

Toolchain 就是一整組的工具集，能讓我們將原始的程式碼編譯為可在目標裝置上運行的執行檔(binary)。工具集當中包含了編譯器、連結器、以及在 runtime 使用的 library。

一般來說，linux 系統上使用的 toolchain 都是基於 GNU 專案發展的套件而來，但近幾年間 Clang 編譯器也是另一種不錯的選擇。

GNU 工具鏈通常包含三種要件:

- Binutils: 一組包括 assembler、linker 之類的已編譯工具集。
- GNU Compiler Collection(GCC) : 根據版本不同可以提供給不同語言做編譯使用。
- C library : 一個依照 POSIX 標準化過的 API，可以提供應用程式一個與作業系統內核溝通的標準介面。

除此之外，還需要一份 Linux kernel 的 標頭檔(header)，這份檔案中包含了用來直接存取內核所需的定義檔和 constant，在與特定的 linux 元件互動時也會需要這份檔案。

而 toolchain 又分為 原生 (Native)、跨平台 (Cross)，原生就是 toolchain 以及其所產生的程式是運行在同類型、甚至是同一部系統上，而跨平台則是 toolchain 可以在與目標系統不同類型的作業系統上運行，所以非常適合嵌入式開發。

而我們選用 crosstool-NG 作為我們的工具鏈

首先從 crosstool-NG 的 Git repo 下載目前最新的版本，並且按照指令解壓縮並建立前端選單系統

```shell
$ git clone https://github.com/crosstool-ng/crosstool-ng.git
$ cd crosstool-ng
$ ./bootstrap
$ ./configure --prefix=${PWD}
$ make
# make install
```

參數 `--prefix=${pwd}` 意思是讓程式安裝在目前的工作路徑下，避免安裝在預設位置 `/usr/local/share` 可能會需要 root 權限問題。

### 組建 BeagleBone Black 的工具鏈

crosstool-ng 可以組建出不同搭配的工具鏈，他也有涵蓋許多不同架構的範本，BeagleBone Black 的架構是 TI AM335x SoC 系統單晶片，含有 ARM Cortex A8 核心，在 crosstool-NG 中選擇最接近的範本為 `arm-cortex_a8-linux-gnueabi`。

`bin/ct-ng` 為啟動 crosstool-ng 選單的指令

我們輸入以下來更改設定檔

```shell
$ bin/ct-ng cortex_a8-linux-gnueabi
```
使用設定選單指令 menuconfig 修改設定內容

```shell
$ bin/ct-ng menuconfig
```
打開選單後，對以下內容做變更

- 在 **Paths and misc opeitons** 中停用 **Render the toolchain read-only**
- 在 **Target options | Floating point** 裡，選擇 **hardware (FPU)**
- 在 **Target options** 中的 **Use specific FPU** 輸入 neon

如果想在工具鏈安裝後增加額外的函式庫，第一點是必要的，這在後續課程中會在說明，第二項則是啟用 eabihf 介面，給有支援硬體浮點數運算元件的處理器架構選擇最適合的浮點數運算集。最後一項則是為了能正確組建出 Linux 內核而必要的設定。

設定完成後記得存檔，接著開始 build
```shell
$ bin/ct-ng build
```
組建過程大概要半小時左右，完成後便可在此路徑找到組建好的工具鏈
`~/x-tools/arm-cortex_a8-linux-gnueabihf`。

假若在 build 的過程中出錯，務必先清除原始資料後再重新 build 一次
```shell
$ bin/ct-ng clean
```

### 編譯

我們可以在 `~/x-tool/arm-cortex_a8-linux-gnueabihf/bin` 底下找到跨平台的編譯器 : `arm-cortex_a8-linux-gnueabihf-gcc`，要使用他必須先將其加入到環境變數中 : 

```shell
$ PATH=~/x-tool/arm-cortex_a8-linux-gnueabihf/bin:$PATH
```

現在可以寫一個簡單的 c 語言程式來測試編譯的效果，以檔案 `hello.c` 為例

```shell 
$ arm-cortex_a8-linux-gnueabihf-gcc hello.c -o hello
```

接著可以使用 `file` 指令來將檔案類型顯示出來，確認是否已經以跨平台的方式編譯完成 : 

```shell 
$ file hello
```

顯示以下訊息
> hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 6.16.0, with debug_info, not stripped

# BootLoader 啟動載入器


 



