「 Embedded Linux 」一覧

組込み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が動作することになり、ファイルシステムの破損などを考慮する必要がなくなります。

 

 


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

ターゲ


組み込みLinux

ぽよんテックでは、Linuxベースの組み込みOSを利用する場合には、標準としてBuildrootのシステムを使用します。

Buildroot

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

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

今後、このブログでも詳しく紹介していきたいと思ってます。