LoginSignup
24
26

More than 5 years have passed since last update.

Raspberry Pi2 Linuxカーネルのクロスコンパイル方法(仮想環境Ubuntu14.04による)

Last updated at Posted at 2016-04-16

目的

Raspberry Pi2のカーネルコンフィグの変更、デバイスドライバの作成などを予定しているため、
備忘録として記載します。
私は2箇所ぐらいハマりましたが、以下の手順に従えばハマらずに済むと思います。

使用機器および知識

 ・OS X El Capitan 10.11.4(Mac)
 ・VirtualBox(5.0.16)
 ・Ubuntu14.04(32bit、isoファイル)
 ・Raspberry Pi2 Model B
 ・microSD(既にRASPBIAN JESSIEがインストールされている状態)
 ・Disk Arbitrator(Mac上のmicroSDオートマウントを阻止するツール)
 ・ターミナル上のコマンド操作

前提知識:クロスコンパイルの必要性

クロスコンパイルを行う理由は、Linuxカーネルのビルド時間を短縮するためです。
貧弱な環境(Raspberry Pi2)でLinuxカーネルをビルドする場合は終了までに何時間もかかりますが、
Mac(Windows)のような高性能なCPUを搭載した環境でビルドする場合は数十分で終了します。
しかし、単純にMacでビルドしたカーネルは、Raspberry Pi上で動作しません。
その理由は、Macの環境(CPU)で動作する事を前提として、ビルドが行われているからです。

そこで、TOOL-CHAINを用いたクロスコンパイルによって、
Mac(Ubuntu)でRaspberry Pi2環境(CPU)向けのカーネルを作成します。

仮想環境の準備

クロスコンパイルには、bash(シェル)が必要です。
Macにはbashが存在しますが、私の環境ではクロスコンパイル中にエラーが発生しました。
そのため、代用としてUbuntu(14.04、32bit)を仮想環境上に導入します。

 1)Mac版のVirtualBoxをダウンロード
 2)VitualBoxをインストール
 3)Ubuntu14.04(32bit)のisoファイルをダウンロード
 4)VirtualBoxを利用して、UbunutuをMacに導入(参考サイト)
 5)Ubuntuの画面サイズ設定を変更(変更しない場合、解像度640×480で固定。参考サイト)
 6)UbuntuとMacの間で、ファイル交換が可能な状態に変更(参考サイト)
 7)以下のコマンドを入力し、/home/username以下のファイル名を日本語から英語に変更 
   例)デスクトップ(日本語) > Desktop(英語)

$ $ LANG=C xdg-user-dirs-gtk-update

最後の7)は、単純にパス指定中に英語・日本語の入力切替を行うのが面倒なだけでなく、
ビルドに失敗しないようにするためです。
以前、私は2byte文字(日本語)のせいで、ビルドにコケた事がありました(別のボードですが)。

クロスコンパイル環境の作成、クロスコンパイルの実行

この節の操作は、全てUbuntu(仮想環境)で行います。

まず、vim(エディタ)とgit(バージョン管理システム)をインストールします。
vimは必須ではありませんが、viより操作しやすいため、このタイミングで導入します。
余談ですが、gitは「Linus Torvalds(Linuxの産みの親)が約2週間で作成」したらしい。素晴らしい。

$ sudo apt-get install vim
$ sudo apt-get install git

続いて、TOOL-CHAINをgitからインストールします。
一連のファイルは、ユーザのホームディレクトリ以下のtools(/home/username/tools)に格納されます。

$ cd ~/
$ git clone https://github.com/raspberrypi/tools

TOOL-CHAINを使用する際に長いパスを記述するのは面倒なため、環境変数を設定します。
以下のコマンドを入力し、.bashrc(bashの設定ファイル)の末尾に2つのPATHを追加します。

$ vi ~/.bashrc

追加するPATH
PATH="$PATH":~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian
PATH="$PATH":~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin

スクリーンショット 2016-04-16 18.52.14.png

続いて、gitからLinuxカーネルのソースを取得します。
Desktop直下にLinuxコードをクローンします。

$ cd ~/Desktop
$ git clone --depth=1 https://github.com/raspberrypi/linux

linuxディレクトリに移動し、Raspberry Pi2用のkernel7.imgを指定します。
その後、Raspberry Pi2用のコンフィグファイル(.config)を作成します。
ここでのBCM2709は正しいSOC(System on a Chip)を指定していませんが、
公式サイト通りなので、気にしない事にします(Raspberry Pi2のSOCは、BCM2836)。

$ cd /home/username/Desktop/linux
$ KERNEL=kernel7
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig

自分好みにカーネルコンフィグを設定します(画像はコンフィグ画面)。
今回、私は"Power Management options > Suspend to RAM and standby"を有効化しました。
(私は変えたいコンフィグ設定が見つけられない事が多いです。恐らく、探し方があるのでしょうね)

$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

スクリーンショット 2016-04-16 19.31.56.png

最後に、以下のコマンドでクロスコンパイルを行います。
30分以上はかかりますので、技術書や漫画を読むなり、ゲームするなり、掃除するなり、暇を潰しましょう。

$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs

ちなみに、64bit版Ubuntuを使用した方は、このタイミングでビルド失敗します(使用するgccが異なるため)。
PATHを以下のように変更すれば、ビルドが通る筈(私は未検証。公式と別の方の報告では成功してます)。

PATH="$PATH":~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64
PATH="$PATH":~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin

microSDに作成したファイル(zImageやモジュール)をインストール

既にmicroSDにはRASPBIAN JESSIEがインストールされている状態と仮定します。

まず、Macに差し込んだmicroSDをUbuntu(仮想環境)に認識させます。
microSDのマウント情報が欲しいので、mountをMacのターミナル上で入力します。
今回は、各パーティションが以下のように割り当てられている事が分かりました。

/dev/disk2s6 on /Volumes/boot (msdos, local, nodev, nosuid, noowners)
/dev/disk2s1 on /Volumes/RECOVERY (msdos, local, nodev, nosuid, noowners)

この2つのパーティションをアンマウントします。

$ sudo umount /dev/disk2s6
$ sudo umount /dev/disk2s1
//もしくは
$ sudo diskutil umountDisk /dev/disk2

次に、VirtualBox vmdkファイル(./sd-card.vmdk)を作成します。
コマンド末尾の"/dev/disk2"は、環境に合わせて変更します。
例えば、マウント情報が"/dev/disk1s1"ならば、"/dev/disk1"と変更します。

$ sudo VBoxManage internalcommands createrawvmdk -filename ./sd-card.vmdk -rawdisk /dev/disk2

"./sd-card.vmdk"と"/dev/disk2"のパーミッション(権限)を
書き込み、読み込み、実行可能状態に変更します。念のため、所有者情報も変更します。
(このパーミッション変更、Macを再起動する度に必要です。面倒)

$ sudo chmod 777 /dev/disk2
$ sudo chmod 777 ./sd-card.vmdk
$ sudo chown username /dev/disk2
$ sudo chown username ./sd-card.vmdk

// usernameは適宜、置き換えなければなりません。

Ubuntuの電源を落として、Oracle VM Virtualマネージャ(VirtualBoxを起動した直後の画面)を
開いた状態にします。
そこから、「設定(①) > ストレージ(②) > ハードディスクの追加(③)」を選択し、
「既存のディスクの選択」を選択します。その後"sd-card.vmdk"を「コントローラ:SATA」に追加します。
私はこのタイミングで「Resource busy」というエラーが出ましたが、
原因はmicroSDが再びマウントされていたからでした。アンマウントすれば、追加できる筈です。
修正.png

Ubuntuを起動し、Ubuntuターミナル上でlsblkコマンドを入力すると、microSD情報が確認できます。
ここで、Ubuntuが起動できなければ、Mac側でmicroSDのマウント状況を確認してください。
アンマウントをしてからUbuntuを起動しても失敗する場合(再びマウントされてしまう場合)、
Disk Arbitratorによって再マウントをブロックします。
Disk Arbitratorの右下にあるModeを"Block mounts"に設定した状態で、
disk2s1(Device欄)を選択した後、unmountボタンをクリックします。disk2s6にも同じ操作をします。
(/etc/fstabを編集してオートマウントを防ぐ事は、El Capitanではできません)
スクリーンショット 2016-04-17 0.16.45.png

Ubunutuが無事に起動できれば、Ubuntuターミナル上でmicroSDをマウントします。

mkdir mnt/fat32
mkdir mnt/ext4
sudo mount /dev/sdb1 mnt/fat32
sudo mount /dev/sdb2 mnt/ext4

モジュールをインストールします。

sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=mnt/ext4 modules_install

Device Treeをインストールし、古いカーネルの情報をバックアップします。
最後にmicroSDをアンマウントしたら、実機で動作確認を行います。

sudo cp mnt/fat32/$KERNEL.img mnt/fat32/$KERNEL-backup.img
sudo scripts/mkknlimg arch/arm/boot/zImage mnt/fat32/$KERNEL.img
sudo cp arch/arm/boot/dts/*.dtb mnt/fat32/
sudo cp arch/arm/boot/dts/overlays/*.dtb* mnt/fat32/overlays/
sudo cp arch/arm/boot/dts/overlays/README mnt/fat32/overlays/
sudo umount mnt/fat32
sudo umount mnt/ext4

以上で、作業は終了です。

参考

KERNEL BUILDING(Raspberry Piの公式ヘルプ)

24
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
26