「 Poyontech Blog 」一覧

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

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

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

 

 


組込みLinuxを起動するまでの基礎知識

Linuxには、サードパーティが提供しているディストリビューションを利用することが一般的ですが、ディストリビューションによって、デスクトップ用、サーバー用など様々な利用形態を、ディストリビューションを提供している組織が想定する利用環境に応じて作成しています。

その中には、組み込みシステム用ディストリビューションなども存在し、有償サポートを利用することによって、ユーザーが想定している組み込みシステムの構築を行っている組織もあります。

組み込みシステムでは、サーバーやルーターといったネットはあるが画面の無い環境、ビデオレコーダーのように画面はあるがネットはない環境、自動販売機や工作機器のように画面もネットも無い環境など、様々な形態が考えられるので、ディストリビューションの、画面を見ながらCDROMからインストールなどのイメージとは全く違うLinuxのインストールが必要になります。

このサイトでは、Buildrootという、ソースコードディストリビューションを利用して、組み込みシステムを構築していく方法を解説していきます。Buildrootは一般的なデスクトップのディストリビューションとは異なり、ソースコードオンリーのディストリビューションで、組み込みシステムにおいて必要最低限のツールをコンパイル、パッケージにするだけでなく、必要なクロスコンパイラ等もコンパイル環境に合わせて構築されるために、かなり厳密に組み込みファームウェアのバージョン管理等も行うことができます。

また、構造も単純なため、x86PC以外でも、各種チップメーカーから出されているリファレンスコードをBuildrootのソースツリーに組み込むことも比較的単純に行うことができます。

 

Initプロセス

 

Linuxカーネルは、起動すると、ルートファイルシステムをマウントし、”init”というプログラムを起動します。”init”は/etc/inittabファイルを参照し、それに記載された動作を行います。

※一部の解説書では”init”が /etc/init.d/rcXXを読み込んでと書いてあるものもありますが、”init”が読むのは/etc/inittabだけです。/etc/inittabの中で、/etc/init.d/rcXXを実行しろと書いてあれば、それを読み込みますし、/etc/hogehogeを読めと書いてあればそちらを読みます。

 

とりあえず、Buildroot標準の/etc/inittabを見てみましょう。

# /etc/inittab

#

# Copyright (C) 2001 Erik Andersen

#

# Note: BusyBox init doesn’t support runlevels.  The runlevels field is

# completely ignored by BusyBox init. If you want runlevels, use

# sysvinit.

#

# Format for each entry: :::

#

# id        == tty to run on, or empty for /dev/console

# runlevels == ignored

# action    == one of sysinit, respawn, askfirst, wait, and once

# process   == program to run

 

# Startup the system

::sysinit:/bin/mount -t proc proc /proc

::sysinit:/bin/mount -o remount,rw /

::sysinit:/bin/mkdir -p /dev/pts

::sysinit:/bin/mkdir -p /dev/shm

::sysinit:/bin/mount -a

::sysinit:/bin/hostname -F /etc/hostname

# now run any rc scripts

::sysinit:/etc/init.d/rcS

 

# Put a getty on the serial port

console::respawn:/sbin/getty -L  console 0 vt100 # GENERIC_SERIAL

 

# Stuff to do for the 3-finger salute

#::ctrlaltdel:/sbin/reboot

 

# Stuff to do before rebooting

::shutdown:/etc/init.d/rcK

::shutdown:/sbin/swapoff -a

::shutdown:/bin/umount -a -r

 

最初のコメント欄を見ると、このファイルはBuildrootではなくてBuildrootで使用しているBusybox由来のファイルであることが分かります。

システム起動直後に実行すべき項目は、sysinitとして記載されています。

::sysinit:/bin/mount -t proc proc /proc

ここでは、最初にporcファイルシステムをマウントしています。

::sysinit:/bin/mount -o remount,rw /

この項目は、ルートファイルシステムを書き込み可能としてマウントしなおしています。これを実行しないと、次のmkdirコマンドが実行できません。

::sysinit:/bin/mkdir -p /dev/pts

ここでは、ptsデバイスを配置するためのディレクトリを作成しています。

::sysinit:/bin/mkdir -p /dev/shm

ここでは、shmデバイスを配置するためのディレクトリを作成しています。

::sysinit:/bin/mount -a

/etc/fstabに記載されているファイルシステムのマウントを行います。

::sysinit:/bin/hostname -F /etc/hostname

Hostnameの設定を行っています。

# now run any rc scripts

::sysinit:/etc/init.d/rcS

ここから、/etc/init.d以下のコマンドを実行して、デーモンの起動を行います。

ptsや、shmを使用しないのであれば、2-4行目は削除しても問題ありません。

 

idのフィールドは、デバイス名を記述します。起動後に、シリアルポートにもログインプロンプトを表示したい場合などでは、idに/dev/ttyS1などと書きます。

次は、runlevelのフィールドですが、Busyboxの/etc/inittabでは、runlevelを無視していることがわかります。Runlevelの概念は、初期のUNIXシステムでは、カーネル起動時のオプションが数字1文字しか指定できなかったために、それを用いて、システムの起動条件を変えるために使用していたのですが、最近のLinux(UNIX)システムでは、カーネル起動時の引数をいろいろ指定することができるので、わざわざrunlevelとして使用する必要もなくなりました。今でも、デスクトップシステムでは、GUIログインと、CUIログインを区別するために利用されることもあるようですが、ほかの引数で代用することも可能ですので、なくても問題ないでしょう。“:”のフォーマットは、他のシステムの/etc/inittabとの互換性のため残してあるようです。

次のフィールドは、起動条件になります。sysinitは起動時に一回だけ実行、respwanは実行したプログラムが終了したら再度実行(ログインプロンプトを出す場合などに使用)、ctlaltdelは Ctrl+Alt+Delが押された場合に実行するプログラムを指定、shutdownはシャットダウンを行う場合に実行するファイルを指定します。

これらによると、起動時は、特殊なファイルシステムのマウントを行い、ホスト名を設定した後で、/etc/init.d/rcSを実行するように指定されれてます。起動後は、コンソールにログインプロンプトを表示し、ログアウトされたら再度表示。Ctrl+Alt+Delが押された場合は、rebootコマンドを実行。シャットダウン時には、/etc/init.d/rcKスクリプトの実行後スワップを無効にしています。

※組み込みシステムでは、”init”自体を置き換えてしまうことも可能です。8Bitマイコンから、Linux環境に移行してきた場合などは、APIやドライバはカーネル提供の物を使い、アプリケーションや、ファイルシステムなどは必要ないとした場合に、”init”をユーザーのプログラムに置き換えてしまうことによって、非常にシンプルな構成のシステムとすることも可能です。8Bitマイコンのプログラムは、それ自体でメモリ管理や、割り込み制御などを行っているので、単純に移植だけをするときなどは、移植のための工数を最小限にすることができます。

 

次に、inittabで指定されている/etc/init.d/rc.Sを見ていきましょう。

 

#!/bin/sh

 

# Start all init scripts in /etc/init.d

# executing them in numerical order.

#

for i in /etc/init.d/S??* ;do

# Ignore dangling symlinks (if any).

[ ! -f “$i” ] && continue

case “$i” in

*.sh)

# Source shell script for speed.

(

trap – INT QUIT TSTP

set start

. $i

)

;;

*)

# No sh extension, so fork subprocess.

$i start

;;

esac

done

 

 

/etc/init.d/rc.Sでは、/etc/init.d以下の Sで始まっているファイルを、アルファベット順に実行していってます。そのうち、.shで終わるものは、再帰的にshellを起動せずに実行し、その他のファイルは、startオプションをつけて実行していってます。この再帰的にshellを実行しないことによる速度アップはたいしたことないと思われますので、あまり気にしなくてもいいでしょう。

このような方式をとるメリットとしては、あるサービスを起動するにあたって、例えばWebサービスはネットワークが起動した後で起動したいとした場合、Webサービスのプログラムのインストーラーは、他のスクリプトの存在や、他のスクリプトの中身を気にせずに、S41以降の番号を起動スクリプトにつけておけばいいということになるので、デスクトップOSのように、ユーザーがプログラムを必要に応じてインストールするような環境では有利に働きます。

一方、組み込みシステムのように、ユーザーがプログラムを追加することは考えなくていいシステムであれば、こういった構成をとる必要はありません。(こちらが使いやすいと思えば、このままでもいいし、他の構成をとった方がいいのであれば、他の構成をとることもできます。)

 

ディストリビューションで用いられているinitrd

 

ディストリビューションで用いられているLinuxのブートプロセスは、

 

ブートローダー

カーネル、initrdの読み込み

カーネル起動

カーネル

initrdをルートファイルシステムとしてマウント

initrdの中の”init”を起動

init

initrdの中のドライバをロード

inittab中で、ロードしたドライバを用いてDISKドライブをマウント

DISKドライブをルートファイルシステムに変更

DISKドライブ中のrcスクリプトを実行

 

といった手順で初期化されていきますが、今回のシステムでは、

 

ブートローダー

カーネル、initrdの読み込み

カーネル起動

カーネル

initrdをルートファイルシステムとしてマウント

initrdの中の”init”を起動

init

initrdの中のドライバをロード

initrdの中のrcスクリプトを実行

といった手順となります。つまり、ルートファイルシステムは、initrdのままアプリケーションを実行することになります。これによって、ディスクドライブがない状況でLinuxが動作することになり、ファイルシステムの破損などを考慮する必要がなくなります。

 

 


コンソールケーブル(追記)

前にここに書いたコンソールケーブルですが、FTDI社のチップでも、偽物チップが出回っているようです。

とりあえず、手元にあるのは、Windows Update後のWindows10でもうまく動作しているので、偽物チップではないようですが、まともなルートで入手しても偽物の場合もあるようですので、今後は注意が必要かもしれません。

まぁ、米軍の装備品の中にも、かなりの割合で偽物チップが紛れてるようですので、非常にややこしい問題です。簡単に鑑定できるものでもないですし… (とりあえず、取引してる中国の業者には、念を押しておかないと…)


ARM SoCとU-Boot

x86プロセッサでの組み込みLinuxの対応作業はソースコードの改変なしでメニューの選択だけで行うことができましたが、ARMプロセッサボードを開発した場合にはソースコードの改変作業が発生します。

各種ドライバを含めたLinuxカーネルの部分は、Kernel Version 3.2以降ではDevice Tree Blobといったメカニズムによってカーネルソースコードの改変が最低限で済むよう設計されています。そのため、新規にARMプロセッサを採用したボード上にLinuxを移植しようとするときに、作業量が最も多くなると思われる部分は、ブートローダの移植になります。

CPUメーカの提供しているリファレンスボードや、開発ツールメーカーの開発ボードなどでは最初からU-BootやRedBootなどのブートローダーが最初から書き込まれており、リファレンスボードでソフト、別の場所でハードの開発を並行して進めて、最後に自社のボードに乗せ換えようとする場合などで、最後の段階においてブートローダがうまく移植できないといった問題が発生することもままあります。ブートローダーの最初の部分は、メインメモリも見えない状態で動く必要がありますので、問題が発生した場合のデバックも簡単ではありません。したがって、リファレンスボードでの開発を並行して行うのであれば、ハードウェアを設計する段階で、製品とリファレンスボードでは全く同じDRAMを使用する、製品ボードにはコネクタは実装しないが、JTAGのパターンを残しておくなどの工夫が重要です。

カーネルのDevice Tree Blobの改変も少々癖があるので、最初は非常にとっつきにくいのと、デバッグがやりにくいといった欠点もありますが、慣れてしまえばなんとかなりますので、いろいろいじってみましょう。

U-Bootをはじめとするブートローダーは、x86 PCでは、最初からマザーボードに実装されているBIOSや、UEFIとして実装されていて、メインメモリの容量や、アクセスタイミング、キーボードや、初期メッセージを出すためのスクリーンの準備など、ハードウェアの構成に依存する部分の初期化作業を行ってくれますが、新規開発ボードではそのBIOSに相当する部分を自分で作る必要があります。

ここで、実際のボードでどのようにU-Bootを移植していくのかを解説していきたいところですが、市販のリファレンスボードや、開発ボードなどでは、ブートローダーはさわるなといった感じのボードが多いですし、CPUのデーターシートがNDA契約がないと見れないボードの開発はしたくないので、実機での開発手順の公開をどのようにしていくかは検討中です。

いまのところ、BeagleBoardなんかがいいのかな?と考えているところです。

 


組み込みシステム用Linuxを作ってみよう x86版(2)

前回の「組み込みシステム用Linuxを作ってみよう(1)」からの続きです

仮想マシンで実行することも考えましたが、仮想マシンで動いたところで動いてる実感に乏しかったので、実機をUSBメモリで起動する方法を解説していきます。当然、同様のことを仮想マシンで実行することも可能ですので、実機を準備するのが面倒な場合は仮想マシンで実行してみてください。

前回作成した、イメージをUSBメモリーに書き込んで、USBブート可能なPCで起動してみましょう。
まずは、USBメモリーのパーティショニングから

% sudo fdisk /dev/sdX

※ sdXは、USBメモリのデバイス名

Command (m for help): n
Partition type:
p primary (2 primary, 0 extended, 2 free)
e extended
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-15196159, default 2048): (Enter)
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-15196159, default 15196159): (Enter)
Using default value 15196159
Command (m for help): a
Partition number (1-4): 1
Command (m for help): w
Command (m for help): q

数値は、メモリによって異なりますが、とりあえず全体をLinuxで使用するように設定します。
続いてフォーマットと、メディアにデーターを書き込むことはないので、定期的なfsckの実行を抑制するためのパラメーターの設定をします。

% sudo mkfs -t ext2 /dev/sdb1
% sudo tune2fs -c -1 -L system /dev/sdb1

次に、MBRを書き込みます。これは、BIOSがセクター0を読み込んでOSを起動するまでのコードが格納されているコードです。このコードは前回ブートローダーにsyslinuxを選択したため、output/build/syslinux-6.03以下にビルドされています。

% sudo cat output/build/syslinux-6.03/bios/mbr/mbr.bin > /dev/sdb

MBRを書き込んだら、ファイルシステムをマウントして、MBR以降のブートローダーのコードを書き込みます。

% sudo mkdir /mnt/usb
% sudo mount -t ext2 /dev/sdb1 /mnt/usb
% sudo output/host/sbin/extlinux --install /mnt/usb

最後に、カーネルとRAMディスクイメージをコピーして、syslinuxのブートメニューを設定してUSBメモリーをアンマウントします。

% sudo cp output/images/bzImage /mnt/usb
% sudo cp output/images/rootfs.cpio.gz /mnt/usb
% sudo cat  << _EOF > /mnt/usb/extlinux.conf
> DEFAULT linux
> PROMPT 0
> LABEL linux
> LINUX bzImage
> INITRD rootfs.cpio.gz
> EOF
> _EOF
% sudo sync
% sudo umount /mnt/usb

これで、起動メディアの完成です。USBブート可能な、PCにメディアを刺して起動すると、今回作成したLinuxが起動するはずです。
起動したLinuxでは、rootでログインして、コマンドを消したり、変な設定をしても、USBメモリを書き込み可能でマウントしない限り、再起動すると元に戻ります。また、書き込み可能メディアをマウントしていないので、シャットダウン処理の必要もありません。(いきなり電源ケ


自分でブログ書いてみて・・・

我ながら、句読点の打ち方とか、接続詞の使い方とか、日本語の基礎がひどいことを読み返してみるとよくわかる。

慣れてくると、もうちょっとまともになるかと思いますので、それまでご辛抱を


なぜ組み込みシステムにLinuxを使うのか

How toの途中ですが、ちょっと読み物を

これから組み込みシステムを開発しようと思っている方は、大きく2つの方向からのアプローチをとっていると思います。

1つは、これまで8Bitマイコンのシステムを作ってきてデーター量の増加や、扱うデバイスの複雑化などによって、より高機能なシステムを利用するためにLinuxを採用してみようというアプローチ。もう一方は、これまでデスクトップOSでシステムを組んできたが、専用機にすることによって、メンテナンス性の向上や、ユーザーの自由度を制限することによって、システムの安定性を望んでの組み込みLinuxを採用してみようというアプローチです。

どちらからのアプローチでも、システムが完成してしまえば、それなりの効果は得られるはずです。しかし、そのためには、これまで組んできたシステムでは全く考慮しなくてよかった部分を考慮する必要が出てきます。

まず、最初にマイコンからのアプローチについて検討してみましょう。

Linuxの基本は、マルチユーザー、マルチタスクのOSです。マルチユーザのOSとは、Aさんでログインしたら、Aさんの環境、BさんでログインしたらBさんの環境が準備されていることを前提としています。8Bitマイコンシステムでは、マルチユーザーを意識したものはほとんど無いと思いますので、この概念を理解して進めるかどうかによって、アプローチ方法が大きく変わります。今後、インターネットにつながって、システムとしてセキュリティを考えていかなくてなならないのであれば、マルチユーザの概念を理解しておく必要があります。

ここでは、温度センサを例に解説していきましょう。一般的な温度センサであれば8Bitマイコンで十分なのですが、一定時間毎に温度を記録してグラフを出しましょう。また、そのグラフはPCやスマートフォンなどからWebブラウザで見えるようにしましょうとなると、LinuxなどのWebサーバーが利用できるOSを採用したほうがいいことにまります。また、データーも永遠に増え続けるので、誰かが操作してバックアップするなりクリアするといったメンテナンスも必要になってきます。このあたりから、マルチユーザーの機能が必要になってきます。メンテナンスを行う権限を持ったユーザーと、見ることだけが可能なユーザーといった2種類のユーザー権限を定義したシステムを考えていく必要が出てくるといった具合です。

また、ファイルシステムいった概念も、8Bitマイコンにはなかったものです。How Toのページでルートファイルシステムをどうするかなどの解説もしてきましたが、マイコンでは、OSもアプリケーションも最終的に1つの実行形式ファイルにリンクしてROMに書き込むといったアプローチが一般的であるのに対して、Linuxでは、ファイルをコピーするコマンド、システムをシャットダウンするコマンドなど、それぞれの機能を別々のファイルとして実現しています。今後、ブートローダーの移植などの話題もこのブログで取り上げていく予定ですが、ブートローダーのプログラムなどは、8Bitマイコンのプログラムに非常に似ています。逆に、一般的に使用されているブートローダの機能を拡張するだけである程度のシステムであれば実現することも可能であるともいえます。

デスクトップOSからのアプローチはどうでしょう

デスクトップOS(Windowsや、一般的なLinuxのディストリビューション)では、システムは、エンドユーザーが使いながら進化させていくことを前提に設計されています。文章を書きたいなら、ワードプロセッサをインストール、セキュリティを向上させるために、ウィルススキャンをインストールなどして、システムの状況は日々進化していくものとして設計されています。一方、組み込みシステムでは、システムそのものの変更は基本的に行われません。工作機械に組み込んだコンピュータの能力が余ってるからといって、工作機械で、ゲームやネットサーフィンをしようとはユーザーも思わないでしょう。逆に、できるからといって、ネットサーフィンの機能などをつけたら、ウィルスなどで工作機械が誤動作でもしようものなら目も当てられません。

そのまま、工作機械を例に話を進めますが、システム設計者は、どのような機能を実現するかだけでなく、機械を組み立てる際に設定すべき項目(モーターがいくつあって、それぞれのモーターの性能、温度センサの位置とそれぞれの意味など)と、エンドユーザーが設定すべき項目(どのモーターに何ミリ径のドリルをつけるかなど)のように、だれが何を設定し、どのように操作するかを考えながら設計する必要がります。特に、設定項目については最低限、シンプルで目的を達成するためにわかりやすくすることが重要です。なんでもできるようにしてしまうと、Linuxなので表計算ソフトを入れてしまえということになりかねません。オープンソースなどのLinuxの便利なツールを最大限に生かしながら、ユーザーにはLinuxであることを意識させない設計が必要です。

Linuxは非常にパワフルなOSで、8Bitマイコンの代わりをすることもできますし、データーセンターの巨大サーバーのようなシステムを構築することができるOSです。どのような機能を追加して、どのような機能を隠蔽していくかは設計者のセンスにかかってきます。

今後、このブログで、8Bitマイコンに近い使い方や、デスクトップOS的な使い方など、様々な例をあげながら解説していく予定です。How Toの解説だけでなく、考え方やアプローチの方法なども追記していきます。

また、ぽよんテックでは、Linuxだけでなく、xxBSDや、Windows、マイコンなどの開発も行っていきますので、よろしくお願いします


組み込みシステム用Linuxを作ってみよう x86版(1)

前回宣言していたBuildrootを用いたLinuxで組み込みシステムをbuildするにはどうすればいいのかを解説していきます。
まぁ、実際に動くコードを作ってみて、最終的なシステムに比べて何が余分で、何が足りないのかが具体的にイメージできたほうがいいと思うので、今回はx86 PC用のコードを生成することにしましょう。
最初にすることは、開発用PCの設定とBuildrootのダウンロードから
開発用PCの設定は、とりあえず、メジャーなLinuxディストリビューションをインストールして、build-essential, ncurses-dev, bison, flexのツールをインストールします。
Debian-Ubuntuの場合には
 % sudo apt-get install build-essential 
 % sudo apt-get install ncurses-dev
 % sudo apt-get install flex
 % sudo apt-get install bison
とすれば、インストールできます。
Fedora,Centosの場合には
% sudo yum groupinstall buildsys-build development-tools
% sudo yum install -y flex
% sudo yum install -y bison
としましょう。開発用のディストリビューションデに依存するのはここ部分ぐらいで、今後の作業で依存するところはほとんどないので、ディストリビューションは、お好みで選んで問題ありません。
続いて、http://www.buildroot.org から、最新版をダウンロードして、解凍、コンフィグメニューを表示します
 % tar xvfz buildroot-2016.02.tar.gz
 % cd buildroot-2016.02
 % make menuconfig
メニューが表示されますので,上から順にシステムに関する情報を設定していきましょう。
2016-03-12
今回は、PC用の設定ですので、Target Architectureに x86_64か、i386を設定します。Target Binary Formatは、デフォルトのままELFで問題ありません。Target Architecture Variant は、使用するCPUに合わせて設定してください。Core i3,i5,i7の場合は、corei7を設定しましょう。ATOMの場合にはatomと設定してください。
Target Options
    Target Architecture (x86_64) --->
    Target Binary Format (ELF) --->
    Target Architecture Variant (corei7) --->
Build Optionsに関しては、デフォルトのままで問題ありません。
Build options --->
    Commands --->
    ($(CONFIG_DIR)/defconfig) Location to save buildroot config (NEW)
    ($(TOPDIR)/dl) Download dir (NEW)
    ($(BASE_DIR)/host) Host dir (NEW)
    Mirrors and Download locations --->
    (0) Number of jobs to run simultaneously (0 for auto) (NEW)
    [ ] Enable compiler cache
    [ ] Show options and packages that are deprecated or obsolete (NE
    [ ] build packages with debugging symbols (NEW)
    strip command for binaries on target (strip) --->
    () executables that should not be stripped (NEW)
    () directories that should be skipped when stripping (NEW)
    gcc optimization level (optimize for size) --->
    *** Stack Smashing Protection needs a toolchain w/ SSP ***
    libraries (shared only) --->
    ($(CONFIG_DIR)/local.mk) location of a package override file (NEW
    () global patch directories (NEW)
続いてToolchainの設定を行います。Toolchainとは、ターゲットの実行形式ファイルを作成するためのクロスコンパイラとそれに付随するツール、ライブラリのことで、一般的なPCでは、プログラムはコンパイルしたPCでそのまま実行するのに対して、組み込みシステムでは、作業用のPCでコンパイルしたファイルを、別のアーキテクチャのPCで実行することになります。
そのため、ターゲットの実行形式を生成するために使用するコンパイラをここで指定します。
この仕組みによって、x86 PC用の組み込みシステムであっても有用な副作用があり、例えば、これから開発しようとしているシステムを今後5年間にわたってメンテナンスしていく必要があるとすると、一般的な、作業用と実行PCが同一の実行形式であるといった環境では、作業用のPCが陳腐化してしまうとコードのメンテナンスが非常に困難になってしまうことに対して、コンパイラやライブラリのバージョンが作業用のPCと独立していることによって、コンパイラのソースコードごと保存しておけば、何年たっても同一の実行形式ファイルが生成できることになります。
今回は、とりあえず動かしてみるための設定なので、デフォルトのままでもいいのですが、日本語環境などにも対応できるように、wcharとi18nを有効にしておきましょう。
X Windowや、Webブラウザなども動かしてみたいならば、C++のオプションと、C Libraryを glibcに変更しておいたほうがいいでしょう。(Webブラウザなどののコンパイルは非常に時間がかかるため、動かしてみるといった観点からはおすすめしません)
今回は動かしてみるのが主目的ですが、実際のターゲットは別のCPUで、チップメーカーから最適化されたコンパイラが提供されている場合などは、ここでコンパイラを設定します。
Toolchain --->
    Toolchain type (Buildroot toolchain) --->
    (buildroot) custom toolchain vendor name (NEW)
    *** Kernel Header Options ***
    Kernel Headers (Linux 4.4.x kernel headers) --->
    C library (uClibc) --->
    *** uClibc Options ***
    (package/uclibc/uClibc-ng.config) uClibc configuration file to us
    () Additional uClibc configuration fragment files (NEW)
    [ ] Enable RPC support (NEW)
    [*] Enable WCHAR support (NEW)
    [*] Enable toolchain locale/i18n support (NEW)
    Thread library implementation (Native POSIX Threading (NPTL))
    [ ] Thread library debugging (NEW)
    [ ] Enable stack protection support (NEW)
    [*] Compile and install uClibc utilities (NEW)
    [ ] Compile and install uClibc tests (NEW)
    *** Binutils Options ***
    Binutils Version (binutils 2.24) --->
    () Additional binutils options (NEW)
    *** GCC Options ***
    GCC compiler Version (gcc 4.9.x) --->
    () Additional gcc options (NEW)
    [ ] Enable C++ support (NEW)
    [ ] Enable Fortran support (NEW)
    [*] Enable compiler tls support (NEW)
    [ ] Enable compiler link-time-optimization support (NEW)
    [ ] Enable compiler OpenMP support (NEW)
    [ ] Enable graphite support (NEW)
    [ ] Build cross gdb for the host (NEW)
    [ ] Purge unwanted locales (NEW)
    () Target Optimizations (NEW)
    () Target linker options (NEW)
    [ ] Register toolchain within Eclipse Buildroot plug-in (NEW)
    [ ] Enable graphite support (NEW)
System configuration のページでは、Loginプロンプトやユーザーの扱いの設定をします。基本はデフォルトのままで問題ないと思いますが、LANを使用したいなら、DHCPインターフェイスにeth0を設定してください。rootのパスワードなどはお好みで
System configuration --->
    (buildroot) System hostname (NEW)
    (Welcome to Buildroot) System banner (NEW)
    Passwords encoding (md5) --->
    Init system (BusyBox) --->
    /dev management (Dynamic using devtmpfs only) --->
    (system/device_table.txt) Path to the permission tables (NEW)
    Root FS skeleton (default target skeleton) --->
    [ ] Use symlinks to /usr for /bin, /sbin and /lib (NEW)
    [*] Enable root login with password (NEW)
    () Root password (NEW)
    /bin/sh (busybox' default shell) --->
    [*] Run a getty (login prompt) after boot (NEW) --->
    [*] remount root filesystem read-write during boot (NEW)
    (eth0) Network interface to configure through DHCP (NEW)
    [ ] Install timezone info (NEW)
    () Path to the users tables (NEW)
    () Root filesystem overlay directories (NEW)
    () Custom scripts to run before creating filesystem images (NEW)
    () Custom scripts to run after creating filesystem images (NEW)
次は、Linuxカーネルの設定です。Kernelのバージョンはhttp://www.kernel.org/を参照して、stableかlongtermになっているバージョンの新しいものを設定してください。わざわざ古いものを選ぶ意味はほとんどありません。
defconfigに関しては、Target Architectureで設定したものを入力してください。
チップメーカから、専用のカーネルが提供されている場合などは、ここでそのカーネルのソースの位置を指定すると、そのカーネルをBuildrootのシステムに組み込むことができます。
Kernel --->
    [*] Linux Kernel
    Kernel version (4.4.3) --->
    () Custom kernel patches (NEW)
    Kernel configuration (Using an in-tree defconfig file) ---
    (x86_64) Defconfig name
    () Additional configuration fragment files (NEW)
    Kernel binary format (bzImage) --->
    Kernel compression format (gzip compression) --->
    [ ] Build a Device Tree Blob (DTB) (NEW)
    [ ] Install kernel image to /boot in target (NEW)
    Linux Kernel Extensions --->
    Linux Kernel Tools --->
Target Packageの項目では、実際のターゲットで動作させたいアプリケーションを選択することができます。この項目も、とりあえず動かしてみるだけであれば特に変更する項目はありませんが、どんなアプリケーションが選択できるかは、一通り眺めてみてみるといいでしょう。
Busyboxというのは、Linuxの基本コマンド群を1つのファイルにして提供しているもので、これとカーネルさえあれば、とりあえずシステムとして起動させることができます。Busyboxを使用することによって、cpコマンドのバージョンや、lsコマンドのバージョンといった細かな管理が必要なくなるので、自前でバージョン管理をする必要のある組み込みシステムでは、非常に有用です。
Target packages --->
    -*- BusyBox
    (package/busybox/busybox.config) BusyBox configuration file to us
    () Additional BusyBox configuration fragment files (NEW)
    [ ] Show packages that are also provided by busybox (NEW)
    [ ] Enable SELinux support (NEW)
    [ ] Install the watchdog daemon startup script (NEW)
    Audio and video applications --->
    Compressors and decompressors --->
    Debugging, profiling and benchmark --->
    Development tools --->
    Filesystem and flash utilities --->
    Fonts, cursors, icons, sounds and themes --->
    Games --->
    Graphic libraries and applications (graphic/text) --->
    Hardware handling --->
    Interpreter languages and scripting --->
    Libraries --->
    Mail --->
    Miscellaneous --->
    Networking applications --->
    Package managers --->
    Real-Time --->
    Security --->
    Shell and utilities --->
    System tools --->
    Text editors and viewers --->
次に、Filesystemの形式の選択です。ここでは、組み込みシステムと通常のデスクトップOSの違いを実感するために、cpioのファイルシステムを選択してみましょう。ファイルシステムのすべてがRAM上で実行され、必要なファイルを消してしまっても、設定を変更しても、リセットすれば元通りといった環境ができます。
Filesystem images  --->
    [ ] axfs root filesystem (NEW)
    [ ] cloop root filesystem for the target device (NEW)
    [*] cpio the root filesystem (for use as an initial RAM filesyste
    [ ] cramfs root filesystem (NEW)
    [ ] ext2/3/4 root filesystem (NEW)
    [ ] initial RAM filesystem linked into linux kernel (NEW)
    *** iso image needs a Linux kernel and one of grub, grub2 or
    [ ] jffs2 root filesystem (NEW)
    [ ] romfs root filesystem (NEW)
    [ ] squashfs root filesystem (NEW)
    [ ] tar the root filesystem (NEW)
    Compression method (no compression)  --->
    ()    other random options to pass to tar (NEW)
    [ ] ubifs root filesystem (NEW)
    [ ] yaffs2 root filesystem (NEW)
Bootloaderの設定です。組み込みシステムの場合、ユーザーにキーボードで起動メニューを選択させるようなことはないと思いますので、シンプルで安定感のあるsyslinuxを選択しています。syslinuxは、旧来のMBR経由のブートサポートしていますので、UEFIのみサポートしているマザーボードで使用する場合には、別のブートローダを選択しる必要があります。
Bootloaders --->
    [ ] Barebox (NEW)
    [ ] grub (NEW)
    [ ] grub2 (NEW)
    *** gummiboot needs a toolchain w/ wchar ***
    [*] syslinux (NEW)
    [ ] U-Boot (NEW)
Host utilitiesの項目では、ターゲットイメージを生成するための拡張ツールを選択します。ターゲットの起動デバイスを、作業用PCで作成する場合などに、デバイスのパーティショニングやフォーマットのためのツールを選択します。
作業用PCにこれらのツールがインストールされている場合には、特にここで選択する必要はありませんが、Toolchainと同様に、メディアの陳腐化などにも対応したい場合には、ここで設定しておくと後々有用かもしれません。
Host utilities --->
    [ ] host aespipe (NEW)
    [ ] host checkpolicy (NEW)
    [ ] host cramfs (NEW)
    [ ] host dfu-util (NEW)
    [ ] host dos2unix (NEW)
    [ ] host dosfstools (NEW)
    [ ] host dtc (NEW)
    [ ] host e2fsprogs (NEW)
    [ ] host e2tools (NEW)
    [ ] host faketime (NEW)
    [ ] host genext2fs (NEW)
    [ ] host genimage (NEW)
    [ ] host genpart (NEW)
    [ ] host gptfdisk (NEW)
    [ ] host jq (NEW)
    [ ] host lpc3250loader (NEW)
    [ ] host mke2img (NEW)
    [ ] host mtd, jffs2 and ubi/ubifs tools (NEW)
    [ ] host mtools (NEW)
    [ ] host openocd (NEW)
    [ ] host parted (NEW)
    [ ] host patchelf (NEW)
    [ ] host pwgen (NEW)
    [ ] host qemu (NEW)
    [ ] host sam-ba (NEW)
    [ ] host squashfs (NEW)
    [ ] host u-boot tools (NEW)
    [ ] host util-linux (NEW)
    [ ] host vboot utils (NEW)
最後に Legacy config optionsですが、ここは昔のBuildrootのリリースとの整合性のために残されている項目なので、初めてBuildrootを使用する場合には設定する必要はありません。
Legacy config options  --->
    *** Legacy options removed in 2016.02 ***
以上の設定が終わったら、
 % make

 とすると、Buildrootのスクリプトが、選択したモジュールのソースコードを次々とダウンロードして、コンパイルしていきます。

コンパイルが終了すると

ダウンロードされたファイルは $(TOPDIR)/dl

展開され、コンパイルされたファイルは $(TOPDIR)/output/build

ターゲ


コンソールケーブル

ぽよんテックではネットワーク機器を中心に企画、開発を行っていく方針なのですが、まだ会社を立ち上げたばかりで、開発するための環境整備に四苦八苦しているところです。

環境整備にあたって、いろいろなケーブルや中古のスイッチなどを準備していて気になったのが、RJ45タイプのコンソールケーブルが様々な機器に使用されているのに、シリアルポートがついているPCはほとんどないので、USBシリアル変換ケーブルを使うことになるのですが、まぁこれも新しいWindows用のドライバがあるとかないとか、めんどくさい状況になっています。また、ドライバがあって、安定した変換アダプタを入手できても、DB9のコネクタはでっかくてじゃまっけだし、機器毎にDB9-RJ45の変換アダプタはついてくるので、どれがどれだかややこしいことになってきています。どうせなら、シリアル変換として安定度のあるFTDIのFT232シリーズを使用したケーブルがほしいんだけど、ケーブルメーカーのホームページにはどのチップを使った製品かなど書いてあることのほうが珍しいし。

そこで、様々なメーカーの機器を一通り触ってみて、RJ45のコネクタのピンアサインはほとんど同じなので、安定した変換チップを使用してたRJ45(Console)-USBの変換ケーブルのまともなやつを常時入手できるようにしておけばいいやとの結論に達しました。

こういうときに頼りになるのが、中国人のお友達で、シリアルーUSB変換ケーブルを作っている工場に連絡して、DB9のコネクタをRJ45に変換して送ってもらう段取りをすれば、商品の出来上がりです。

調べてみたところ、シリアルケーブルをRJ45コネクタで使用するための規格が2種類あって、一方は、Ciscoコンソールケーブル用のピンアサインで、もう一方は、RS-232D EIA/TIA 561という規格です。ネットワーク機器で使用されているのはほとんどがCisco互換ピンアサインみたいです。

少量生産なので、格安というわけにもいきませんが量販店で売っている変換ケーブルと大差ない値段で販売できるようになりました。(秋葉原などでディスカウントで販売されている価格には到底及びません)ラックに並んだ大量のCiscoスイッチをとりあえず初期化したい場合などに重宝します。

商品仕様や、販売方法などは、”その他プロジェクト”のページにて行う予定です。

せっかくのブログなので、裏話を少々

USBシリアル変換ケーブルは元々はドライバも含めて、そんなにめんどくさい商品ではなかったのですが、とあるチップを採用した商品に妙なトラブルが頻発するようになりました。

日に日にトラブルが増えていき、ついにはそのチップを製造した数より多くの問題が発生していたことに気が付いたチップメーカーが調べたところ、世の中に出ている商品のほとんどは、そのメーカーが製造したチップの偽物チップが使用されていたことがわかります。

そのチップメーカーは、新しいチップには偽物を作りにくくなるような工夫をして販売をつづけていますが、大量の偽物にマーケットを壊された商品に関しては、新しいバージョンのWindows用のドライバの公開をやめて、本物を仕入れて商品化していた変換ケーブルメーカーにだけドライバを供給するようにしたようです。

しかし、偽物チップを使用した製品はいまだに市場に氾濫していますし、変換ケーブルメーカーも偽物がほしくて偽物に手を出したところは少数で、本物だと思って使用していたら実は偽物で新しいドラバが手に入らなくて困っているところもたくさんあると思います。

そんなこんなで、USB-シリアル変換はいまだに混乱しています。ライバルがこけたところで漁夫の利を得ているのがFTDIのシリアル変換チップで、ライバルがこけたおかげで値崩れすることもなく安定の商品として普及しています。

最後に一言

FTDIさん、高いです うちはもうかりません


回路図 基板 CAD

ハードウェアの設計では、回路図や、プリント基板(PCB)用のCADソフトが必要となります。ぽよんテックではフリーのEDAツールであるKI-CADを使用していく予定です。

ぽよんテックのような零細企業や、個人では、高価な設計ツール(数千万円もする)を使用することはできませんし、ぽよんテックの商品は原則フリーで提供できる”もの”をと考えていますので、個人でも回路図を参照して問題点や、修正すべき点などを発見できるよう、フリーのツールを使用していく予定です。

KI-CADは、現在コミュニティーで開発が活発に行われているため、今後、個人や中小メーカーを中心に普及していくものと考えられます。