2015年2月16日 星期一

Raspberry Pi2 (ARM Cortex-A7) 上編譯Raspbain Kernel



手上拿到了 Raspberry Pi 2 的板子,第一件事情當然就是先去官網下載最新版的Raspbian來安裝了。

http://www.raspberrypi.org/downloads/

寫這文章時Raspbian的更新日期是 2015-1-31。把檔案抓下來燒到microSD卡裡面就可以開機了。但是想在新的系統上開發核心的話,還是需要重編 Kernel。

相關文章: 在Raspberry Pi 上面建立編譯 kernel module 環境之懶人包

-- 2015-07-15 -- 更新 -- 編譯的kernel 帶有Device Tree的功能...
相關文章: 編譯 kernel 4.0.y with device tree:


cross-compile的工作是在按在桌機上的 Debian作業系統裡進行的。

在重新Compile之前要先得到目前版本的.config檔:

登入 Raspbian on Pi2 之後,從系統之中得到.config檔並存到家目錄之下:

zcat /proc/config.gz > ~/.config
然後把Pi2關機,將microSD卡拔下來插到桌機上的讀卡機裡,登入Debian系統之後可以用df指令看是否有自動掛載成功,成功的話會看到類似下面的訊息:
...
/dev/sdb2 ... /media/1263ae8d-aaf3-41b6-9ac0-03e7fecb5d6a /dev/sdb1 ... /media/boot
這樣之後新編譯好的Kernel檔安裝時,就可以直接用複製貼上的方式。

登入桌機上的Debian就可以開始建立Cross-Compiler 環境了。需要準備的東西有Raspbian作業系統原始碼和Cross-Compiler程式。

先在家目底下建立一個rpi2的子目錄然後進入,把要用的東西都放這裡。

mkdir ~/rpi2/ cd ~/rpi2/
一開始先去抓 Raspbian 作業系統原始碼,可以使用git到https://github.com/raspberrypi/linux去下載:

git clone https://github.com/raspberrypi/linux
Cross-Compiler,一樣可以用git 到https://github.com/raspberrypi/tools去clone下來。

git clone https://github.com/raspberrypi/tools
裡面準備了在 Linux版本的GCC for ARM,32bit和64bit版本都有。

32bit 版本的 GCC for ARM在~/rpi2/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/ 。

64bit 版本的 GCC for ARM 在~/rpi2/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/ 。

所以要去修改家目錄下的.bashrc檔,讓系統可以找到可以用的 GCC for ARM:

如果使用的Debian作業系統是32bit,則在~/.bashrc的在最後一行加入:
export PATH=$PATH:~/rpi2/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin
如果使用的Debian作業系統是64bit,則在~/.bashrc的在最後一行加入:
export PATH=$PATH:~/rpi2/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
重新登入一次,使剛剛修改好的.bashrc設定值生效。成功 的話可以輸入arm之後連按兩下tab鍵看看有沒有顯示一堆 arm-linux-gnueabihf- 開頭的執行檔,有的話表示設定生效了。

可以用下面這個指令看一下這個GCC for ARM的版本號碼是多少: (這裡是4.8.3)

arm-linux-gnueabihf-gcc --version
之後如果要在Pi2板子上直接編譯Linux系統核心的話,Pi2子板上的GCC版本要儘量和編譯核心時使用的GCC版本號碼一樣。

接著我們要把剛剛在Pi2上的Raspbian取得的.config複製到Debian系統裡存放Rasbian 原始碼的目錄底下(在這裡,應該要放在~/rpi2/linux/):

cp /media/1263ae8d-aaf3-41b6-9ac0-03e7fecb5d6a/.config ./
這樣就可以開始進行編譯Kernel了。

cd ~/rpi2/linux/ export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabihf- make oldconfig make menuconfig make
完成編譯之後我們先建立資料夾~/rpi2/modules/ ,把編譯完的modules先安裝到這個資料夾:

cd ~/rpi2/ mkdir modules cd ~/rpi2/linux make modules_install INSTALL_MOD_PATH=../modules/
編譯完成之後,在~/rpi2/linux/arch/arm/boot/ 的目錄底下會多出一個zImage的檔案就是核心檔。

先將舊Kernel備份:

mv /media/boot/kernel7.img /media/boot/kernel7.img.backup
再安裝新的核心檔:

sudo cp ~/rpi2/linux/arch/arm/boot/zImage /media/boot/kernel7.img
這邊特別說明一下,舊版的Pi板的核心檔預設檔名為 kernel.img,而新Pi2板的核心檔預設檔名為kernel7.img。所以在microSD卡的boot磁區會同時看到這兩個檔,使作業系統可以在新舊兩個板子上都可以跑。

接下來安裝modules和firware:

sudo cp -Rf ~/rpi2/moudles/lib/modules /media/1263ae8d-aaf3-41b6-9ac0-03e7fecb5d6a/lib/ sudo cp -Rf ~/rpi2/moudles/lib/firmware /media/1263ae8d-aaf3-41b6-9ac0-03e7fecb5d6a/lib/
如果想要在Pi2板子上編譯module的話,記得順便把Kernel Source給複製到microSD卡上:
sudo cp -Rf ~/rpi2/linux/ /media/1263ae8d-aaf3-41b6-9ac0-03e7fecb5d6a/home/pi/ 之後就可以把microSD 卡從桌機上移除並裝到Pi2板上開機了。

Pi2開機成功之後,如果想要在Pi2板上編譯kernel module的話,除了之前有複製一份Kernel Source到microSD卡上之外,記得還要重建/lib/module/3.18.7-v7+/目錄底下的 build連結和 source連結,以及安裝相同版本的GCC

sudo ln -s /home/pi/rpi2/linux/ /lib/module/3.18.7-v7+/build sudo ln -s /home/pi/rpi2/linux/ /lib/module/3.18.7-v7+/source
/proc/version這個檔案裡面有目前使用的kernel7.img當初是用哪些版本的kernel source以及GCC等等的資訊,可以用cat指令顯示裡面的內容。
cat /proc/version
在這個範例裡面,在Debian上面我用來跨平台編譯Pi2 kernel 的 GCC 是version 4.8.3 Linaro GCC,所以進到Pi2系統裡面要編譯自已寫的module的話,也要用相同版本號碼(4.8.3) 的GCC,不過寫文章的時候用apt指令能安裝到的最新版本是4.8.2。不過在目前編譯出來的module在insmod進去核心之後都還沒發生什麼問題。


安裝完之後,記得做一下設定把預設的GCC版本變成gcc-4.8。 sudo apt-get install gcc-4.8 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 20 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 50 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.6 20 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50
然後到kernel Source目錄底下執行make modules_prepare這個指令,之後才能成功編譯自已寫的module....。 cd /home/pi/rpi2/linux/ make modules_prepare








沒有留言 :

張貼留言