Raspberry Pi
Raspbian

Raspberry Pi 2 kernel セルフコンパイル

Raspbian で起動している Raspberry Pi 2 上で kernel をコンパイルする手順です。

arm アーキテクチャーの Linux 環境を作成する場合にはコンパイルの速い x86/x86_64 のクロスコンパイル用ホスト環境を作成して行うことが多いですが、
Raspberry Pi 2 のように比較的速いマシンであればセルフコンパイルしてしまうという方法もあります。
USB Wifi のドライバーなどビルド済みの kernel source が必要な場合や kernel のビルドオプションを変えたいといった場合に
Raspberry Pi 2 だけで作業を完結できます。

以下の手順は Raspbian Wheezy でも Jessie でも共通です。

必要パッケージ

まず kernel のビルドに必要なパッケージをインストールします。

$ sudo apt-get install bc ncurses-dev

gcc、make、git は最初から入っています。

Wheezy の場合は gcc が 4.6.3、Jessie の場合は gcc が 4.9.2 になります。

この version の違いが kernel source のビルドに影響することはまずありませんが、
kernel source の外部のドライバーをビルドする際には gcc のオプションやマクロの違いから
ドライバーの source の修正が必要になる場合があります。

kernel source 取得

/usr/src に移動し、git で kernel source を取得します。

beat@raspberrypi ~ $ cd /usr/src/
beat@raspberrypi /usr/src $ sudo -s

kernel 本体

root@raspberrypi:/usr/src# git clone --depth 1 https://github.com/raspberrypi/linux.git -b rpi-4.1.y
Cloning into 'linux'...
remote: Counting objects: 52876, done.
remote: Compressing objects: 100% (50356/50356), done.
remote: Total 52876 (delta 4012), reused 17583 (delta 1851), pack-reused 0
Receiving objects: 100% (52876/52876), 142.62 MiB | 1.96 MiB/s, done.
Resolving deltas: 100% (4012/4012), done.
Checking connectivity... done.
Checking out files: 100% (49946/49946), done.

firmware

root@raspberrypi:/usr/src# git clone --depth 1 https://github.com/raspberrypi/fi
rmware.git
Cloning into 'firmware'...
remote: Counting objects: 4077, done.
remote: Compressing objects: 100% (2200/2200), done.
remote: Total 4077 (delta 1702), reused 2305 (delta 1576), pack-reused 0
Receiving objects: 100% (4077/4077), 75.59 MiB | 1.21 MiB/s, done.
Resolving deltas: 100% (1702/1702), done.
Checking connectivity... done.
Checking out files: 100% (3777/3777), done.

2015年10月15日現在 rpi-4.1.y branch は 4.1.10 kernel になっています。

ビルド準備

checkout した kernel source のディレクトリに移動し、
configs モジュールをロードして現在起動中の kernel の config を取得、
ビルドの準備をします。

root@raspberrypi:/usr/src/linux# cd linux
root@raspberrypi:/usr/src/linux# modprobe configs
root@raspberrypi:/usr/src/linux# zcat /proc/config.gz > .config
root@raspberrypi:/usr/src/linux# cp ../firmware/extra/Module7.symvers Module.symvers

config の反映

root@raspberrypi:/usr/src/linux# make oldconfig
scripts/kconfig/conf  --oldconfig Kconfig
#
# configuration written to .config
#

現在起動しているのと同じ version なので、make oldconfig では新規に追加されたオプション項目を有効にするかどうかは聞かれずそのまま完了します。

ビルド

ビルドします。
Raspberry Pi 2 の CPU は 4 core あるので -j4 で4並列実行して zImage、modules、dtbs を一括してビルドしてもいいのですが
メモリの使用量が多くなりすぎて swap を設定しないと途中で hung してしまうことがあったので
並列実行せず1つずつ順番に実行しました。
また、time でビルド時間を計測しています。

zImge

root@raspberrypi:/usr/src/linux# time make zImage 2>&1 | tee make1.log
〜〜 中略 〜〜
  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready

real    76m45.564s
user    76m33.100s
sys     3m42.070s

modules

root@raspberrypi:/usr/src/linux# time make modules 2>&1 | tee make2.log
〜〜 中略 〜〜
  IHEX    firmware/yam/1200.bin
  IHEX    firmware/yam/9600.bin

real    214m43.233s
user    204m52.790s
sys     10m32.480s

dtbs

root@raspberrypi:/usr/src/linux# time make dtbs 2>&1 | tee make3.log
〜〜 中略 〜〜
  DTC     arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dtb
  DTC     arch/arm/boot/dts/bcm2709-rpi-2-b.dtb

real    0m10.528s
user    0m3.110s
sys     0m1.650s

インストール

セルフコンパイルしているのでそのままインストールできます。

modules

root@raspberrypi:/usr/src/linux# make modules_install
〜〜 中略 〜〜
  INSTALL /lib/firmware/yam/9600.bin
  DEPMOD  4.1.10-v7+

dtb

root@raspberrypi:/usr/src/linux# ls arch/arm/boot/dts/*.dtb
arch/arm/boot/dts/bcm2709-rpi-2-b.dtb
root@raspberrypi:/usr/src/linux# cp arch/arm/boot/dts/*.dtb /boot/
root@raspberrypi:/usr/src/linux# cp arch/arm/boot/dts/overlays/*.dtb /boot/overlays/
root@raspberrypi:/usr/src/linux# cp arch/arm/boot/dts/overlays/README /boot/overlays/

zImage
Raspbian は /boot/ に Raspberry Pi 用の zImage(kernel.img) と Raspberry Pi 2 用の ARMv7 の zImage(kernel7.img) が置かれています。
Raspberry Pi 2 用をビルドしたものに置き換えます。

root@raspberrypi:/usr/src/linux# cp /boot/kernel7.img /boot/kernel7.img.old
root@raspberrypi:/usr/src/linux# scripts/mkknlimg arch/arm/boot/zImage /boot/kernel7.img
root@raspberrypi:/usr/src/linux# ./scripts/mkknlimg arch/arm/boot/zImage /boot/kernel7.img
Version: Linux version 4.1.10-v7+ (root@raspberrypi) (gcc version 4.9.2 (Raspbian 4.9.2-10) ) #1 SMP PREEMPT Fri Oct 16 22:21:16 JST 2015
DT: y
283x: n

再起動

ビルドした kernel で動作させるため再起動します。

# reboot

ビルドした kernel で起動している状態では以下のようになっています。

pi@raspberrypi:~$ uname -a
Linux raspberrypi 4.1.10-v7+ #1 SMP PREEMPT Fri Oct 16 22:21:16 JST 2015 armv7l GNU/Linux

以前の kernel の uname -a とビルド時刻やビルド時のロケール設定が変わっているのがわかります。

pi@raspberrypi:~$ uname -a
Linux raspberrypi 4.1.10-v7+ #821 SMP PREEMPT Sat Oct 10 00:16:28 BST 2015 armv7l GNU/Linux

更新履歴

2015/10/29 初稿掲載

Satoshi OTSUKA

BC::labsへの質問は、bc9-dev @ googlegroups.com までお願い致します。
トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   最終更新のRSS
Last-modified: 2015-11-05 (木) 19:50:14 (3321d)