Raspberry Pi 除了是個很方便的小玩具之外,同時也非常適合用他來學習和 Linux 以及 Linux Kernel 的相關知識,本篇將講解如何自己編譯最新的 Linux Kernel 給你的 Raspberry Pi 使用。
取得編譯用的 toolchain 與工具
若要進行跨平台編譯,相對應的 toolchain 是必要的,讓我們來說說如何取得 toolchain。
若你是 Gentoo Linux 的使用者,你可以透過 crossdev 建立專用的 toolchain,更完整的資訊,請參考 Raspberry Pi - Gentoo Wiki 。
Rosia rpi # crossdev -S -v -t armv6j-hardfloat-linux-gnueabi
除此之外,在 GitHub 也有開發 Raspberry Pi 所需要的工具,裡面也包含了預先
編譯好的 arm-bcm2708hardfp-linux-gnueabi
這個 toolchain,因此我們也
把他下載到我們的電腦裡。
git clone git://github.com/raspberrypi/tools.git
下載 Linux Kernel
Raspberry Pi 使用的 kernel 可以在 GitHub 上面獲得,或是你也可以下載 mainline kernel 來進行編譯。
git clone https://github.com/raspberrypi/linux
注意到在 GitHub 上面的 kernel 有許多不同的 branch,請選擇你想要使用的 branch 來使用。
coldnew@Rosia ~/rpi/linux $ git branch -a * rpi-3.10.y remotes/origin/HEAD -> origin/rpi-3.10.y remotes/origin/master remotes/origin/rpi-3.10.y remotes/origin/rpi-3.11.y remotes/origin/rpi-3.12.y remotes/origin/rpi-3.2.27 remotes/origin/rpi-3.6.y remotes/origin/rpi-3.8.y remotes/origin/rpi-3.9.y remotes/origin/rpi-patches
編譯 Raspberry Pi 的 Linux Kernel
修改當前 shell 的環境變數
因為我們是進行跨平台編譯,因此編譯的時候要加入
ARCH
以及CROSS_COMPILE
的參數,這邊採用偷懶的做法,直接將資訊覆蓋到目前的 shell 上,這樣 在目前的 shell 就是用於編譯 arm 平台的開發環境了。註:若是在 Raspberry Pi 上進行編譯,此步驟可以省略。
export ARCH=arm export CROSS_COMPILE=armv6j-hardfloat-linux-gnueabi-
若你是使用預先編譯好的 toolchain,請將 armv6j-hardfloat-linux-gnueabi- 更改成你的 toolchain 的資訊。
取得 Raspberry Pi 的 kernel config
如果你手邊有 Raspberry Pi,可以登入他並使用以下方式取得目前 Raspberry Pi 的 Kernel Config。
pi@raspberrypi:/home/pi$ zcat /proc/config.gz > rpi-config
Rapsberry Pi 的 Linux Kernel config 可以在
arch/arm/configs/
下面找 到,共有以下幾個coldnew@Rosia ~/rpi/linux $ (cd arch/arm/configs/ && ls bcmrpi*) bcmrpi_cutdown_defconfig bcmrpi_emergency_defconfig bcmrpi_defconfig bcmrpi_quick_defconfig
選擇你想要用的 kernel config,在這邊我選擇 bcmrpi_defconfig
coldnew@Rosia ~/rpi/linux $ make bcmrpi_defconfig
設定自己想要的 kernel config
選擇好預設的 config 後,接著就可以進行設定並加上自己需要的 kernel 功能。
coldnew@Rosia ~/rpi/linux $ make menuconfig
編譯 kernel
由於我們在前面已經修改了
ARCH
和CROSS_COMPILE
這兩個環境變數, 因此編譯 Kernel 只需要用 make 就夠囉~coldnew@Rosia ~/rpi/linux $ make
編譯完成後,會產生
arch/arm/boot/Image
檔案,你可以使用imagetool-uncompressed.py
將他產生成 kernel.img,若你沒有這個程式, 請到 GitHub 下載。coldnew@Rosia ~/rpi/tools/mkimage $ ./imagetool-uncompressed.py ../../linux/arch/arm/boot/Image
完成後可以在當前目錄下看到 kernel.img 這個檔案
coldnew@Rosia ~/rpi/tools/mkimage $ ls args-uncompressed.txt boot-uncompressed.txt first32k.bin imagetool-uncompressed.py kernel.img
安裝 kernel module 到臨時目錄
為了方便將 kernel modules 放置到 SD 卡裡面,這邊我們將 kernel modules 安裝 到 ../modules_build 去。
coldnew@Rosia ~/rpi/linux $ INSTALL_MOD_PATH="../modules_build" make modules_install
完成後,在 ../modules_build 資料夾裡面可以看到如下的目錄結構
coldnew@Rosia ~/rpi/modules_build $ tree -L 2 . └── lib ├── firmware └── modules 3 directories, 0 files
後面會提到如何將這裡面的 firmware 和 modules 資料夾安裝到你的 SD 卡 裡面。
取得最新的 firmware
Raspberry Pi 開機時,會預先讀取 SD 卡上面的 firmware,很可惜的是,這些 firmware 並未公開原始碼,所以若你有更新你的 kernel,建議是取得最新的 firmware binaries。
git clone https://github.com/raspberrypi/firmware.git
更換 SD 卡上的 Kernel 以及 Kernel Module
更換 firmware
要更換 SD 卡上面的遇編譯好的 firmware,要進行以下兩個步驟
- 將 firmware/boot 資料夾內的以下幾個檔案複製到你的 SD 卡 (boot 資料
夾或是第一個分割區)
- bootcode.bin
- fixup.dat
- start.elf
- 將
firmware/hardfp/opt
複製到 SD 卡上面的 /opt
- 將 firmware/boot 資料夾內的以下幾個檔案複製到你的 SD 卡 (boot 資料
夾或是第一個分割區)
更換 kernel
更換 kernel 只需要將你剛剛產生的
kernel.img
蓋掉 SD 卡上面的 kernel.img 即可。更換 kernel modules
將前面你使用
make modules_install
安裝到 modules_build 裡面的firmware
以及modules
複製到你的 Raspberry Pi SD 卡的根目錄下面的 /lib 資料 夾下,替換原本的/lib/firmware
以及/lib/modules
這兩個資料夾。