Buildrootの設定について

Buildrootの設定について、makeのオプションなどの解説です。

Buildrootのドキュメントを読めば書いてあることしか書いてませんが、ドキュメントのどこかを探すのが面倒な項目なので、ここにアップしておきます。

Buildrootの設定の変更

Buildroot - カーネル設定の変更

make linux-menuconfig

Linuxカーネルの設定を行います

デスクトップシステムでは、様々なデバイスの追加、削除をユーザーが行うことを想定して、デバイスドライバの大部分をモジュール構成にして実装することが多いですが、組込みシステムにおいては、不特定のデバイスの追加を想定する必要がありませんので、デバイスドライバはカーネルと一緒にコンパイルしておくことをお勧めします。

起動時にドライバをロードしておくことによって、Plug&Playの動作不良や、カーネルとモジュールのバージョンの差異などを気にする必要がなくなります。

実例

www.kernel.org にて配布されているLinuxの構成では、Intel社の1000BaseTチップであるIGBドライバは標準では無効に設定されています。(各ディストリビューションで、有効に再設定されて使用されていることが多いです)ここで、IGBドライバを有効にしておかないと、ネットワークが利用できなくなるので、有効に設定しましょう。

Buildroot - busyboxの設定変更

make busybox-menuconfig

Linuxの基本コマンドセットの追加、削除を行います。

組込みシステムにおいて、使用しないコマンドを減らすことによって、メモリ領域やセキュリティ上の問題を軽減することができます。

Buildrootシステムでは、ファイル一覧の表示コマンド「ls」や、ファイルのコピーコマンド「cp」などの基本コマンドはBusyboxで提供されているものを使用することになっています。(詳しくは、http://www.busybox.org を参照)

ここで、デバッグ中はほぼすべてのコマンドを使用するが、組込みシステムの実環境では使用しないコマンドを削除するなどの設定を行うことができます。

「getty」や「login」コマンドを削除してしまえば、ログインできないシステムにするといったことも可能です。

Buildroot - Buildrootシステムの設定の変更

make menuconfig

Buildrootシステム全体の設定を行います。クロスコンパイラのバージョン、使用するライブラリの選択、パッケージの選択などシステムに関する様々な設定を行うことができます。

Buildroot - パッケージの追加

Buildrootの環境で、ユーザーの作成したプログラムをターゲットにインストールするには、実行ファイルを、“output/target”以下にコピーして、“make”を実行すれば”initrd”に統合されて、実行環境が作成されるのですが、”make“一発ですべてが作成される環境を作っておいたほうが、ユーザープログラムの数や種類が増えたときに、バージョン管理などもしやすくなるので、便利です。

ここでは、ユーザーが作成したパッケージをBuildrootのビルドツリーに組込も方法を解説していきます。

とりあず、ユーザープログラムが“make”コマンドでビルドできる物として、存在している場合にBuildrootシステムのパッケージとして追加する方法を解説します。

Buildroot - autotoolパッケージの追加

automake パッケージをBuildrootのビルドツリーに組み込む方法を解説します。

automakeパッケージとは、オープンソースソフトウェアとして世の中に出回っているソフトウェアの多くが採用しているコンパイル方式で、ソースコードをダウンロードした後、「configure」「make」「make install」の順でコマンドを実行してインストールする形式のソフトウェアです。

デフォルトでフルセットをインストールすると、「man」コマンドで参照できるドキュメント関連もすべてインストールされてしまうので、組込みシステムで使用しないマニュアル類をインストールしないような「configure」スクリプトや、パッチなどを準備する必要があります。

また、一部のパッケージでは、「make」時にセルフテストを実行しながらビルドするものもあるので、クロス開発環境が標準のBuildrootシステムでは、それらを回避するためのパッチを作成する必要がある場合もあります。

Buildroot - CMAKEパッケージの追加

CMAKEパッケージは、一部のオープンソースソフトウェアで利用されているビルドシステムで、automakeと同等のことを実行しますが、独特の癖があるので、CMAKE用のスクリプトと、パッチを準備する必要があります。

Buildroot - 特定パッケージのリビルド

make [package-name]-rebuild

Buildroot - スケルトン

起動スクリプトや、Linuxとして動作させるための設定ファイル群のようなテキストファイルは、Buildrootのスケルトンとして、「system/skeleton」に準備されています。

初期の設定を変更したい場合などは、ここのファイルを変更するか、buildrootのPOST-Buildスクリプトを使用することになります。

処理の追加

この項目は、どのような機器を開発していくかによって、様々な方法が考えられますが、組込みシステム一般として、考慮しておくべき必要がある処理について記載しておきます。

設定項目

まったく同じものを量産するのではない限り、各種機器の設定が必要になります。今回のシステムでは、書き込み可能なファイルシステムを準備してこなかったので、ここで、設定の保存方法について解説していきたいと思います。

設定とは、ネットワーク機器であればMACアドレスや、IPアドレスといったもの、Webサーバーなどであれば、管理者ユーザーのパスワードなど、機器によって様々な項目を設定する必要があり、その設定項目についても、MACアドレスやシリアル番号のように工場出荷時に設定しておくべきもの、IPアドレスのように設置時に設定し原則変更しないもの、パスワードのようにユーザーの都合で常時変更が入るもの、ログのように常時変更されるものなど、様々な項目が考えられます。

工場出荷時に設定しておくべき項目

工場出荷時に設定される項目については、一般的に、ハードウェアに専用の格納領域があり、そこに保存されていることが多いです。

例えば、PCでは、EthernetのMACアドレスは、ネットワークコントローラに付随しているROMに保存され、デバイスドライバのロード時にそれを読み込むことになっています。組込みシステムでは、SoCにイーサネットコントローラが内蔵され、MACアドレス専用のROMがつけられない場合や、ROMのコストや設置面積を削減したい場合などの理由で、他の領域に保存してあることもあります、その場合には、その内容をデバイスドライバのロード時に通知するなどの仕組みをLinuxのカーネルに追加する必要があります。

設置時に設定しておくべき項目

設置時に設定しておくべき項目を保存するには、記憶メディアに専用の領域を設け、そこに保存する必要があります。

一般的にブートデバイスに、パーティションを作成しておき、設定変更がなされた場合に、一時的にその領域を書き込み可能で再マウントした後に、設定情報を書き込み、書き込みが済んだら、即座にアンマウントするといった方法をとります。

設定情報については、ファームウェアファイルとは別の設定情報ファイルを作成し、特定領域に保存しておく必要がありますが、設定用のUIを準備する必要はありません。

ユーザーの操作により設定される項目

設置時に設定しておくべき項目との違いは、設置時に設定する項目は、管理者がいつ書き込みを行っているかを把握できるのに対して、ユーザーの操作は任意の時間に発生するため、機器の電源断による設定項目の破損に対応しておく必要があるといった点にあります。

このような環境下では、設定項目を保存する領域を2つ以上確保して、一方の書き込みが済んで、アンマウントが完全に完了したことを確認した後に、もう一方の保存領域に同じものを書き込むといった手段が必要になります。

読み込み時は、最初の保存領域への保存が完了して、アンマウントが済んでいれば、ファイルシステムがクリーンな状態になっているため、ファイルシステムの健全性フラグを確認して、クリーンなファイルシステムから設定情報を読み出すようにします。

また、ユーザーによる設定変更用のUIを準備する必要があります。

設定変更用のUIは、コマンドラインによる設定か、WebUIによる設定が一般的です。

保存のタイミングは、UIによる操作によりますが、設定変更とのタイミングが重要で、設定変更、設定保存の組み合わせは、以下のような状況を考慮する必要があります。

1. 設定変更、保存無し

設定変更だけを実行し、保存を行わない。管理者パスワードや、IPアドレスの変更など、ユーザーが入力を間違えてしまった場合、設定変更と同時に保存を行ってしまうと、操作中に電源断などが発生した場合に操作不能な状況に陥ってしまうような設定変更を行う場合、いったん設定変更だけを行い、変更に問題がないことをユーザーに確認させたうえでの設定保存を行う必要がある場合の項目になります。

2. 設定保存

1.のように設定変更だけを行った場合に、確認が完了したのでその設定を保存するためのコマンドです。

3. 設定変更と同時に保存

デバイスの追加、ユーザーの追加といった日常的に行われる操作で、誤った入力を行っても、やり直しのきく項目で、ユーザーの操作の煩雑さを削減したい場合のコマンドです。

4. 設定保存後再起動で、設定を反映

初期スクリプトでのみ設定を反映できる項目の設定変更を行った場合に実行されるコマンドです。デバイスの設定をリアルタイムで反映できない場合、設定保存後、機器を再起動することによって設定を反映させます。

ユーザーの操作は煩雑になりますが、サービスを起動したままの設定変更の必要がないため、実装は楽になります。

# mount -t vfat /dev/sda2 /config

#

常時変更される項目

常時更新される可能性のある情報を安全に保存するには、外部の記憶装置を用いる以外に、不意の電源断などから安全に保存する方法はないのですが、組み込みシステムでは以下のような方法を用いて、ファイルシステムの健全性を保ちつつある程度までの情報を保存する方法がとられることがあります。

1.  通常の保存は、RAMディスク上に行う

2.  一定時間毎に、RAMディスク上に保存された情報に変更があったかどうかの確認を行う。

3.  情報に変更があった場合には、3.の「ユーザーの操作により設定される項目」で示したように、複数のデバイスまたはパーティションに情報を保存する。

といった手順を行うことによって、ファイルシステムを破壊することなく、情報の保存を行うことができます。

ファームウェアのバージョンアップ

システムとして完成させるためには、将来のファームウェアのバージョンアップにも対応しておく必要があります。

今回、ファームウェアとして、作成するファイルは1つだけになりますので、そのバージョンの確認と、新しいファームウェアのバージョンを比較して、新しいファームウェアが存在する場合には、それに変更するためのインターフェイスを作成しておく必要があります。この機能がない場合には、一旦組み立てラインまで機器を戻さないとファームウェアのアップデートができないことになりますので、必ず実装しておきましょう。

ファームウェアのバージョンの確認には、ファイルのタイムスタンプや、ファイル名などを用いる方法があります。

また、ネットワークを用いてアップデートする場合など、セキュリティが要求される分野では、これから入れ替えようとするファームウェアが正しい開発元で開発されたものであるかどうかを確認するための仕組みも必要となります。そのための、コード署名ロジックなどの実装も考慮しておきましょう。