アールテクニカ地下ガレージ

アールテクニカ株式会社の製品開発・研究開発・日々の活動です

Raspberry Pi 3とリアルタイムカーネル(1)[RT Preempt導入編]

Author

コイデマサヒロ

 

Raspberry Pi 3(以下RPi3)は、そこそこマシンパワーがありデスクトップLinuxが動くので音楽制作用途としても使えるのではないかと試行しています。いろいろなソフトが動くもののレイテンシーが大きくなってしまうのが難点です。

そこでリアルタイムカーネルを試してみようと思います。ここでいうリアルタイムというのは本来はレイテンシーを下げるという意味では無いのですが、CPUのスケジューリングが正確になることによって、結果的にオーディオ再生のレイテンシーを下げることができるはずです。音楽などマルチメディア制作向けのLinuxは、必ずリアルタイムカーネルを採用しています。

今回は Raspbianにリアルタイムカーネル(rt-preemptという種類のもの)を自分でビルドして導入する手順を紹介します。

 

導入の方法概要

リアルタイムカーネルは、ノーマルなカーネルにリアルタイムカーネル用のパッチをあててビルドして作成します。
カーネルは、RPi3でビルドすると時間がかかるので、PC上でクロスコンパイルします。。OSはLinuxを使います。WindowsやMac上でも作成可能のようですが、ビルド環境を整えるのが大変です。

最近のPC/Macであれば、VMwareやVirtualBox、Parallels等の仮想環境上のLinuxで問題ないと思います。Debian系のLinuxであれば使い方はRaspbianに近いので使い方も問題ないはずです。また、クロスコンパイル用のツール類も用意されていますので、手順さえ間違えなければそれほど難しくないと思います。

Raspbian用のカーネルのビルドについては本家でも情報が出ています。
https://www.raspberrypi.org/documentation/linux/kernel/building.md
基本な流れではこれを踏襲しますが、このページの方法がスマートでしたので参考にしました。

 

ビルド環境の準備

まず、リアルタイムカーネルをインストールするノーマルのRaspbianを用意します。本家よりイメージをインストールし、基本的なセットアップを済まし、

$ sudo apt-get update
$ sudo apt-get upgrade -y
$ sudo apt-get dist-upgrade -y

を実行して最新状態にしておきます。

 カーネルをビルドするPCを用意します。僕は、ここからcinamon desktopの64bit版をダウンロードして使いました。32bit版、64bit版のどちらもで構いません。lxdeは、raspbianの元になっているものですので、こちらのほうが馴染みやすいかもしれません。Linuxの使い方はここでは省略します。

また、linuxからsshでRPi3に入れるようにしておいてください。

 

カーネルのバージョンの確認

パッチをあてるカーネルとリアルタイムパッチのバージョンを揃える必要があります。
パッチはここからダウンロードします。
https://www.kernel.org/pub/linux/kernel/projects/rt/
バージョンごとにフォルダに分けられています。新しいバージョンだと、4.4.12 か4.6.2 があります。カーネルと一致させた方が良いですが、4.4、4.6という2桁目まであわせれればうまくいく可能性があります。 

raspbianのカーネルは、以下でダウンロードできます。
https://github.com/raspberrypi/linux.git
branchがrpi-4.4.yといったようにバージョンごとに分けられています。
パッチのバージョンとあわせると、4.4.yか4.6.yが利用できることになります。
細かいバージョンを確認すると、それぞれ4.4.13と4.6.2となっています(2016.6.22現在)。どうせなら新しい方をということで、今回は、4.6.2 で試してみたいと思います。

 

現在のRPiの上のカーネルのバージョンを確認するには、

$ uname -a

とすれば確認できます。例えば

Linux raspberrypi 4.4.13-v7+ #894 SMP Mon Jun 13 13:13:27 BST 2016 armv7l GNU/Linux

と表示されます。

 

ノーマルカーネルのソースにパッチをあてる

まずはLinux側です。Linux上のターミナルで

$ cd

といれます。これでユーザーホームの位置になる移動するはずです。この位置を基準に作業をします。

 

ノーマルカーネルのソースをダウンロードします。カーネルのgitをまるっとコピーすると1G以上あり、完了までかかりますので、利用したいバージョンのソースだけダウンロードすることにします。

$ git clone -b rpi-4.6.y --depth 1 https://github.com/raspberrypi/linux.git

 linuxという名前のフォルダが作成されそこにダウンロードされます。そのLinuxフォルダに移動します。

$ cd linux

 そこにリアルタイムパッチをダウンロードします。

$ wget https://www.kernel.org/pub/linux/kernel/projects/rt/4.6/patch-4.6.2-rt5.patch.gz

パッチはいろいろな圧縮形式で置かれていますのが、gz形式のものをダウンロードします。パッチを適用します。

$ zcat patch-4.6.2-rt5.patch.gz | patch -p1

エラーが出なければ成功です。マイナーバージョンが違うカーネルにパッチを当てている場合で、ここでエラーが表示されたら、あきらめて他のバージョンで試してみましょう。

 

ビルド用ツールのダウンロード

 ユーザーホームに戻ります。

$ cd ..

 ビルドするためのツール類をダウンロードしてきます。やはりサイズが大きめなので、最新状態のみにしておきます。

$ git clone https://github.com/raspberrypi/tools.git -depth 1

 

環境変数のセット

 ビルド用に環境変数をセットします。これは一時的なものですので再起動/再ログイン等で戻ります。逆に途中で再起動などすると設定が戻ってしまいますので注意してください。 

$ export ARCH=arm

 次のコンパイラの指定ですが、usernameは各環境に合わせて変えてください。

32bit版Linuxの場合;

$ export CROSS_COMPILE=/home/username/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- 

64bit版Linuxの場合;

$ export CROSS_COMPILE=/home/username/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-

 次のビルドしたカーネル類の配置場所の指定です。usernameは利用環境にあわせて変えてください。

$ export INSTALL_MOD_PATH=/home/username/rtkernel

RPi3用のカーネルをビルドするという指定です。

$ export KERNEL=kernel7

 

カーネルのビルド設定 

カーネルソースのディレクトリに移動し、ビルドの設定をします。

$ cd linux
$ make bcm2709_defconfig

別の方法もあります。これはRPi実機の設定を直接適用させます。僕はこちらを利用しました。この場合、RPi側で、ターミナルから以下のコマンドを実行し、設定を書き出します。

$ sudo modprobe configs

 Linux側に戻り(linuxフォルダ内で)、PRiから設定ファイルをダウンロードしてきます。raspberryは、RPiのIPアドレスを入れます。通常ですと、raspberrypi.local としても大丈夫です。

$ scp pi@raspberry:/proc/config.gz ./

raspbianのパスワードが求められますので、入力すればRPiとsshで接続され、先ほど作成した設定ファイルがLinux側にコピーされます。

コピーしてきた設定ファイルを所定の場所に書き出します。

$ zcat config.gz > .config

これで実機から設定を引き継ぐことができました。

次にリアルタイムカーネルのためのビルドの設定行います。
linuxフォルダ内で、

$ make menuconfig

とするとターミナル内に設定画面が表示されます。確認、変更するのは2点です。

  • CONFIG_PREEMPT_RT_FULL 
    Kernel Features ---->
    Preemption Model (Fully Preemptible Kernel (RT)) ---->
    Fully Preemptible Kernel (RT)
  • Enable HIGH_RES_TIMERS
    General setup ---->
    Timers subsystem ---->
    High Resolution Timer Support

パラメータはスペースキーで確定させます。また変更したらSaveをしておきましょう。exitを押していけば元の(上位の)画面に戻ります。後者の設定は、通常はデフォルトに設定されいるので変更無しのはずです。

 

カーネルのビルドとインストール

実際に各モジュール等をビルドしていきます。最後に -j2とか-j4とかすれば多少ビルドが早くなります。(数値はCPUコア数が上限です。)

$ make zImage modules dtbs
$ make modules_install

次にビルドした必要なファイル類をまとめます。linuxフォルダ内にいるという前提です。

$ mkdir $INSTALL_MOD_PATH/boot
$ ./scripts/mkknlimg ./arch/arm/boot/zImage $INSTALL_MOD_PATH/boot/$KERNEL.img
$ cp ./arch/arm/boot/dts/*.dtb $INSTALL_MOD_PATH/boot/
$ cp -r ./arch/arm/boot/dts/overlays $INSTALL_MOD_PATH/boot

これで必要なファイル類が、rtkernelフォルダにまとめられました。これでRPi3にリアルタイムカーネルをインストールできるのですが、ここで一つ問題があります。rtkernelフォルダにはカーネル以外にもFirmware等も含まれているようですが、Wifi用のFirmwareはオープンソースではないため含まれていません。このままリアルタイムカーネルをインストールするとWifiに接続できなくなります。

有線LANでも接続できる場合は、リアルタイムカーネルをインストール後に、

$ sudo apt-get install firmware-brcm80211

とすればFirmwareをインストールすることができます。
そうでない場合は、ここでWifiのFirmwareを追加しておきます。

$ cd ..

でホーム位置に戻り、

$ git clone --depth 1 https://github.com/RPi-Distro/firmware-nonfree

でFirmware類をダウンロードしてきます。

WifiのFirmwareを所定の場所にコピーします。

$ cp -r ./firmware-nonfree/brcm80211/brcm ./rtkernel/lib/firmware

まとめたファイルをRPiに送るため圧縮します。  

$ cd $INSTALL_MOD_PATH
tar czf /tmp/kernel-4.6.2-rt5-v7+.tgz *

圧縮したファイルをsshでRPi3に送ります。

$ scp /tmp/kernel-4.6.2-rt5-v7+.tgz pi@raspberrypi:/tmp

raspberrypiは PRi3のIPアドレスに変えてください。

ファイルが送信できたらRPi側でインストール作業を行います。

以下のとおり実行してください。

$ cd /tmp
$ tar xzf kernel-4.6.2-rt5-v7+.tgz
$ sudo rm -r /lib/firmware/
$ sudo rm -r /boot/overlays/
$ cd boot
$ sudo cp -rd * /boot/ $ cd ../lib $ sudo cp -dr * /lib/

これでインストールできました。
ただし、このままだSDカードへのアクセスもLow Latency Modeになってしまい不都合がでてくるかもしれませんので、

$ sudo nano cmdline.txt

として

sdhci_bcm2708.enable_llm=0

という行を加えればこれを避けることができるようです。

$ sudo reboot

として再起動すれば、リアルタイムカーネルで起動するはずです。

 

$ uname -a 

として、

Linux raspberrypi 4.6.2-rt5-v7+ #1 SMP PREEMPT RT Sat Jun 11 02:10:12 JST 2016 armv7l GNU/Linux

という感じで PREEMPT RT と表示されればOKです。(時刻はビルドした日付です)

リアルタイムカーネルにしても、OSの使い方はノーマルカーネルのときと変わりませんのでいろいろ試してみましょう。
ただし

$ sudo rpi-update

を実行するとノーマルのカーネルに書き換わってしまうため気をつけてください。逆にノーマルのカーネルに戻したい場合は有効です。また、通常のアップデートでもカーネルのアップデートが来る場合もあります。その場合は、一旦ノーマルカーネルに戻して再度リアルタムカーネルをインストールするのが良いと思います。

 

最後に

リアルタイムカーネルの導入は多少手間ではありますが、必要なツール類がそろっていることもあって、手順さえ間違えなければ簡単だと思います。 

 
 
Author

コイデマサヒロ

ディレクター、プロデューサー、ギタリスト。mimiCopyをはじめ弊社リリースの全てソフトウェア製品の企画を担当。ネイティブアプリ開発がメインでOS問わず対応可。dubバンドのギタリストとしても活動中。

スポンサーリンク