2014年8月5日 星期二

Embedded Linux on Cubieboard2 (I): Toolchain 與 Bootloader

系列前言

    Cubieborad2 是深圳 Cubie Tech 公司 Cubieborad 系列ARM架構開發版的第二代。搭載了Allwinner A20(ARM Cortex-A7)@1GHz Dual Core處理器,1GB DDR3 記憶體,其他外部配備有 3.4GB NAND Flash,最高支援到 64GB 的 micro SD 插槽,HDMI,10/100 Ethernet,2 x USB 2.0 HOST,1 x mini USB OTG,SATA3 。
    Cubieboard 最吸引我的是它完全開源的軟硬體與廣大社群,除了頁面整理亂到不行+不定期死機的Wiki以外
    本系列文章是紀錄我個人在移植一個基本且盡量輕小的 Linux 系統到 Cubieboard2 (簡稱cb2)時的一點紀錄。
    作者本身才剛踏入嵌入式系統這個領域,文章裡如有哪邊需要修正請不用客氣的在留言中提出。

本篇Outline

  1. Cross compile toolchain
  2. 製作 Bootloader

Cross Compile Toolchain

    我 toolchain 用的是大名鼎鼎的 linaro toolchain。基本上把 binary 載下來就好了,但是由於不明原因,編譯 cb2 的 kernel 時請用 gcc 4.7 的,至於其他像是 bootloader 就可以用 gcc 4.8。以本篇為例,我 cross compiler 的 gcc 名字就是 arm-linux-gnueabihf-gcc,值得一提的是 gnueaibhf 的 "hf" 代表的是 hard float,簡單來說就是用硬體運算浮點數,以前比較舊的處理器運算浮點數的時候是用整數的指令來做運算,後來才有專門是作浮點數運算的硬體指令出現,速度自然是比較快的。

製作 Bootloader

    Cubieboard2 使用的是 U-boot 當作他的 bootloader,我沒那麼厲害可以從零開始移植 U-boot 到這塊板子,所以我就先下載官方移植好的 U-boot 自己做編譯和安裝。基本上像 bootloader 這麼底層的東西,文件和原始碼都在 Allwinner 的 wiki 和 github 裡。
首先,下載 U-boot 原始碼。
git clone https://github.com/linux-sunxi/u-boot-sunxi.git
sunxi 是 Allwinner 底下 ARM SoC 的代稱。U-boot 設定 cross compiler 的方式非常方便,跟眾多大型專案一樣,把環境變數 CROSS_COMPILE 設定成 toolchain 名字的 prefix 就可以了。
export CROSS_COMPILE=arm-linux-gnueabihf-
注意最後面有一個"-",因為在 Makefile 裡它是這樣展開(示意):
CC = $(CROSS_COMPILE)gcc
 接下來設定 U-boot:
make Cubieboard2_config
至於全部裝置的列表是在 boards.cfg 裡,所以如果是 cb1 的 U-boot 的話就是 make Cubieboard_config。 config 完之後就大力的輸入 make 吧。

接著,你會在 U-boot 的目錄下看到一個 u-boot-sunxi-with-spl.bin 的檔案,那就是我們要燒進去的 bootloader。事實上,上面的檔案是由兩個東西組成的:U-boot 和 SPL,SPL 就是 Second Program Loader,簡單來說就是負責載入第三階段的 U-boot,描述了許多載入時所需要的硬體資訊,如果要分開燒的話 SPL 在底下的 spl 資料夾的 u-boot-spl.bin。

    下圖是 cb2 SD 卡開機區段的 layout。


SD 卡的分區我是把 boot 與主系統分開來,這樣的優點是主系統可以使用 ext4 檔案系統,因為這個官方提供的 U-boot 在讀取kernel等開機所需檔案時,目前只能支援 fat32, ext2 等比較老的檔案系統(mainline 的 U-boot 已經支援 ext4 囉),所以像是另外一種沒有把 boot 分開來的切割方式,就只能使用有支援的檔案系統。切割工具的部份,我個人試過很多像是 fdisk, sfdisk 等,最後還是覺得:用 GParted 就可以了,又快又方便。

boot 分割區我是把它格式化成 fat32(下次再來試試 ext2 看有什麼差別)外加 LBA,在 fdisk 裡面 fat32(LBA) 的型態代碼是 0x0C,但奇怪的是我用最新版的 fdisk 怎麼這種型態不見了只剩下普通 fat32,至於在 GParted 裡,LBA 是一個旗標,跟 boot 旗標一樣,要按右鍵管理旗標的那個地方。要注意的是,依照上表,磁碟前 1MB 是要保留的,雖然現在的工具都會保留 1MB,在 fdisk 裡,通常就是從第 2048 sector 開始割(通常 1 sector 是 512 bytes,0.5 KB),最後記得 boot 分割區要加 boot 旗標。我的磁碟分割就如下圖。


(畫紅底線的就是磁碟旗標)

在燒錄前,我們先要依 layout 把前 1MB先清乾淨,依本人慘痛的經驗,如果把 partition table 也清掉的話將會是一場災難,雖然 partition table 不一定如 layout 說的有 8KB 那麼大,但我們還是乖乖的保留前 8KB 吧。
dd if=/dev/zero of=/dev/sdX bs=1024 count=1016 seek=8
請把上面的 sdX 改成你自己 SD 卡的裝置檔。接著,把 bootloader 燒進去。
dd if=/path/to/u-boot-sunxi-with-spl.bin of=/dev/sdx bs=1024 seek=8
Bootloader 的準備到這邊基本上就告一個段落了。

沒有留言:

張貼留言