組み込みデバイスでのLinuxシステム開発

PDAをいじるのは面白くて役に立つ

組み込みLinuxの開発は、ブートローダー、Linuxカーネル、GUIの大きく3つの層に分けられます。この記事では、これら3つの層に関する基本的な考え方をいくつかご紹介します。とくに組み込み開発にかかわり始めたばかりの読者なら、利用できるブートローダー、簡易ディストリビューション、あるいはファイルシステムやGUIにさまざまなものがあることから、圧倒されるように思われるかもしれません。しかし、この選択肢の豊富さは、実際のところ、ありがたいことであり、それぞれのニーズに合わせて開発環境やユーザー環境を作り上げていくことができるのです。この記事でLinuxでの組み込み開発を概観することで、これらのことについてよく理解していただけるのではないかと思います。

Anand Santhanam, Software engineer, IBM Global Services

Anand K Santhanamは、インド、マドラス大学でコンピュータ・サイエンスのエンジニアリングの学士号を取得しています。1999年7月からインドのIBMグローバル・サービス (ソフトウェア研究所) に勤務しています。IBMのLinuxグループのメンバーで、主にARM-Linux、デバイス・ドライバー、組み込みシステムにおける電源管理について研究を進めています。その他、O/Sの内部構造やネットワークの分野に興味をもっています。



Vishal Kulkarni, Software engineer, IBM Global Services

Vishal Kulkarniは、インド、マハラシュトラにあるShivaji大学で電子工学の学士号を取得しています。1999年3月からインドのIBMグローバル・サービス (ソフトウェア研究所) に勤務しています。その前は、米国のIBMオースチンに1年半以上勤務していました。IBMのLinuxグループのメンバーで、主にARM-Linux、デバイス・ドライバー、組み込みシステムにおけるGUIについて研究を進めています。その他、O/Sの内部構造やネットワークの分野に興味をもっています。



2002年 3月 01日

Linuxは、組み込みの分野で着実な進歩を遂げています。LinuxはGPL (稿末の参考文献参照) として扱われていますので、自分のPDAやパームトップや装着デバイス (wearable device) にLinuxをカスタマイズすることに興味のある人は誰でも、カーネルやアプリケーションを自由にインターネットからダウンロードし、移植や開発に着手することができます。Linux系統の数多くの製品が、組み込み / リアルタイム市場の要求に応えるものとなっています。たとえば、RTLinux (Real-Time Linux)、uclinux (MMUを持たないデバイス向けのLinux)、Montavista Linux (ARM、MIPS、PPC対応版のLinux)、ARM-Linux (ARM上のLinux) などなどです (本稿で触れている用語や製品については、参考文献を参照してください。リンクできるようになっています)。

組み込みLinuxの開発は、大きく3つの層に分けることができます。ブートローダー、Linuxカーネル、およびグラフィカル・ユーザー・インターフェース (GUI) の3つです。本稿では、これら3つの層に関する基本的な考え方をいくつか紹介したいと思います。まず、ブートローダーとカーネルとファイルシステムの間の相互関係を少し解明したいと思います。次に、ファイルシステム、GUI、ブートローダーとして用意されている数ある選択肢のいくつかについて詳しく調べてみたいと思います。

ブートローダー

ブートローダーは通常、どんなハードウェアにおいても、実行されるコードの最初の部分です。デスクトップなどの通常のシステムでは、ブートローダーは、普通、MBR (マスター・ブート・レコード)、すなわちLinuxが置かれているディスクの1番目のセクターにロードされます。デスクトップなどのシステムの場合、通常、BIOSは、ブートローダーに制御を渡します。ここで疑問が生じてきます。(ほとんどの場合) BIOSを搭載していない組み込みデバイスに、誰がブートローダーをロードするのだろうかと。

この問題に対処するには、一般に2つの技法が使用されます。特別なソフトウェアを使うか、小さなブートコードを使うかです。

特別なソフトウェアの場合、システムに搭載されているフラッシュ・デバイスとリモートから直接やりとりを行い、フラッシュ内の特定の部位にブートローダーを書き込むことができます。フラッシュ・デバイスは、記憶装置と同様の働きをする特殊なチップで、持続性があります。すなわち、リブート時に記憶内容が消去されることがありません。

このソフトウェアは、ターゲット (組み込み開発の場合、組み込みデバイスのことを、よくターゲット と呼びます) 上のJTAGポートを使用します。JTAGポートとは、外部入力 (通常は、ホスト・マシンから) からの命令を実行するために使用されるインターフェースのことです。フラッシュに直接書き込みを行うための一般的なツールがJFlash-linuxです。JFlash-linuxは、さまざまなフラッシュ・チップをサポートしています。ホスト・マシン上で実行され (通常はi386マシン。本稿では、i386マシンのことを指してホストということにします)、JTAGインターフェース経由でパラレル・ポートを使って、ターゲットのフラッシュ・チップにアクセスします。したがって、もちろん、ターゲットは、ホストと通信を行うために、パラレル・インターフェースを装備していなければなりません。Jflash-linuxには、Linux版とWindows版の両方があります。起動するときは、コマンドラインから以下のように入力します。

Jflash-linux <bootloader>

組み込みデバイスには、(数バイト程度の)小さなブートコードを装備する類のものもあります。このコードは、DRAMの設定をいくつか初期化し、ターゲット上のシリアル (あるいはUSBやイーサネット) ポートを有効にして、ホスト・プログラムと通信できるようにします。ホスト・プログラムやローダーは、このようにして確立された接続を使用して、ブートローダーをターゲットに転送し、それがフラッシュに書き込まれるというわけです。

フラッシュに書き込まれ、制御を受けたブートローダーは、以下のような作業を実行します。

  • CPU速度の初期設定
  • メモリーの初期化。メモリー・バンクの有効化やメモリー構成レジスターの初期化など
  • シリアル・ポートの初期化 (ターゲットに装備されている場合)
  • 命令 / データ・キャッシュの使用可能化
  • スタック・ポインターの設定
  • パラメーター領域の設定、パラメーター構造体やタグの構築 (これらのブート・パラメーターは、カーネルがルート・デバイスやページ・サイズ、メモリー・サイズなどを認識する際に使用しますので、これは重要な処理です)
  • POST (Power On Self Test) の実行。接続されているデバイスを識別し、問題があれば報告する
  • 電源管理のサスペンド / レジュームのサポート処理
  • カーネルの開始位置へのジャンプ

ブートローダー、パラメーター構造体、カーネル、ファイルシステムなどからなるシステムのメモリー・レイアウトは、通常、以下のようなものとなるでしょう。

リスト1. 一般的なメモリー・レイアウト
/* Top Of Memory */ 
		Bootloader
 		Parameter Area 		Kernel 		Filesystem
	/* End Of Memory */

組み込みデバイス用Linux向けに一般に無料で出まわっているブートローダーには、たとえば、Blob、Redboot、Bootldrなどがあります (リンク先については、参考文献を参照)。これらのブートローダーは、すべて、ARMベースのデバイス用のLinuxであり、インストールには、Jflash-linuxツールが必要です。

ターゲットのフラッシュへのインストールが完了したら、ブートローダーは、上記の初期化作業を実行します。この時点で、ブートローダーは、ホストからカーネルやファイルシステムを受信できる状態になっています。カーネルをロードできたら、ブートローダーは制御をカーネルに渡します。


ツールチェーンのセットアップ

ツールチェーンのセットアップを行うことで、(ターゲット上で実行される) カーネルとアプリケーションをコンパイルするビルド環境を、ホスト・マシン上に作成します。これは、バイナリー実行レベルでのホストとの互換性が、ターゲット・ハードウェアにない可能性があるからです。

ツールチェーンは、カーネルやアプリケーションをコンパイル、アセンブル、リンクするための一連のコンポーネントからなります。これらのコンポーネントには、以下のようなものがあります。

  • Binutils -- バイナリー・ファイルを扱うためのユーティリティー・コレクション。この中には、arasobjdumpobjcopyなどのユーティリティーが含まれます。
  • Gcc -- GNU Cコンパイラー。
  • Glibc -- すべてのユーザー・アプリケーションがリンクに必要とするCライブラリー。カーネルなどのモジュールで、Cのライブラリー関数を使わずにおきたい場合は、これを使わずにコンパイルすることも可能です。

ツールチェーンをビルドすることで、クロス・コンパイラー環境が出来あがります。ネイティブ・コンパイラーは、それが実行されるのと同じ種類のプロセッサー向けの命令セットをコンパイルします。これに対して、クロス・コンパイラーは、あるタイプのプロセッサー上で実行されますが、コンパイルする命令セットは別タイプのプロセッサー用のものです。クロス・コンパイラー・ツールチェーンを1からセットアップするのは、簡単な仕事ではありません。ソースをダウンロードし、パッチを行い、環境設定を行い、コンパイルし、ヘッダーをセットアップし、インストールを行うなどの他、いろいろな作業を伴います。さらに、このようなビルド作業を完全に行うには、大量のメモリーやハード・ディスクが必要となります。それだけでは済まないというかのごとく、ビルドの際には、依存関係や環境設定やヘッダー・セットアップといった問題に絡んで、さまざまな問題が持ちあがることがあります。

したがって、コンパイル済みのバイナリーがインターネット上で入手できるとしたら、幸運といえます (ただ、それが現時点では、ほとんどARMベースのシステムに限られている点は少し問題ですが、それもやがて変わっていくことでしょう)。コンパイル済みのツールチェーンで、よく出まわっているものには、たとえば、Compaq (おなじみのLinux)、LART (LART Linux)、Embedian (Debianをベースにしつつも、現在ではDebianと関係がない) などがあります。すべて、ARMベースのプラットフォーム向けです。

カーネルのセットアップ

Linuxのコミュニティは、新しいハードウェア向けの機能やサポートを追加したり、カーネルのバグを修正したり、全体にかかわる改良を適宜行うなど、非常に活動的です。その結果、ほぼ6ヶ月おきに、あるいはそれより短いのペースで、安定したLinuxツリーの新しい版が出されています。アーキテクチャーごとに、いろいろな種類のカーネル・ツリーやパッチが、いろいろなグループによって管理されています。何かのプロジェクトにカーネルを選択する場合、最新の版がどの程度安定しているか、プロジェクトの要求やハードウェア・プラットフォームに対応しているかどうか、プログラミング環境が快適かどうか、など無形の項目について、評価しておく必要があります。また、自分のアーキテクチャーに合わせるには、ベースのカーネルにどんなパッチを当てて調整を行う必要があるのか、逐一調べておくことも非常に重要です。

カーネルのレイアウト

カーネルのレイアウトは、アーキテクチャーに固有な部分とアーキテクチャーに依存しない部分とに分けられます。カーネルの中のアーキテクチャーに固有な部分は、最初に実行され、ハードウェア・レジスターの設定を行い、メモリー・マップを設定し、アーキテクチャーに固有な部分の初期化を行います。それから、カーネルの中のアーキテクチャーに依存しない部分に制御を渡します。システムの残りの部分は、この第2フェーズで初期化されます。カーネル・ツリー下のディレクトリーarch/ には、それぞれのアーキテクチャー (MIPS、ARM、i386、SPARC、PPCなど) に合わせて、別々のサブディレクトリーが作成されます。これらのサブディレクトリーには、kernel/ やmm/ といったサブディレクトリーが設けられ、メモリーの初期化、IRQの設定、キャッシュの設定、カーネル・ページ・テーブルの設定といったことを行うためのアーキテクチャーに固有なコードが格納されます。これらの機能は、カーネルがロードされ、制御を受けとったときに、最初に呼び出されます。システムの残りの部分が初期化されるのは、その後です。

カーネルは、利用可能なシステム・リソースやブートローダーの機能にしたがって、vmlinuxかImageかzImageとしてコンパイルします。vmlinuxとzImageの主な違いは、vmlinux が実際の (圧縮されていない) 実行コードであるのに対して、zImage は、おおよそ同じ情報を収めている自己解凍型の圧縮ファイルという点です。ただし、圧縮されているのは(通常Intelが課している) ブート時の640 KBという制約に対応するためです。これらの形式の定義については、Linux Magazine の記事 "Kernel Configuration: dealing with the unexpected" (参考文献 参照) を参照してください。

カーネルのリンクとロード

ターゲット・システムに合わせてカーネルのコンパイルができたら、ターゲット・システムのメモリー (DRAMなりフラッシュなり) にブートローダーを使ってカーネルをロードします (ブートローダーは、先にターゲットのフラッシュにロードしておく)。ブートローダーは、シリアルかESBかイーサネットのポートを使ってホストと通信を行い、ターゲットのフラッシュかDRAMにカーネルを転送します。カーネルをすべてターゲットにロードし終わったら、ブートローダーは、カーネルのロードされたアドレスに制御を渡します。

カーネルの実行モジュールは、たくさんのオブジェクト・ファイルをリンクしたものになっています。これらのオブジェクト・ファイルは、テキスト、データ、初期データ、ベースなど、いろいろなセクションからなっています。これらのオブジェクトは、リンカー・スクリプトと呼ばれるファイルによって、リンクされ、ロードされます。リンカー・スクリプトの働きは、入力オブジェクト・ファイルの各セクションを出力ファイル上に対応付けることにあります。すなわち、すべての入力オブジェクト・ファイルをリンクして1個の実行モジュールにするわけです。実行モジュールの各セクションは、それぞれ指定のアドレスにロードされるようになります。vmlinux.lds は、arch/<target>/ ディレクトリーに置かれるカーネル・リンカー・スクリプトで、カーネルの各セクションをリンクし、それらのセクションをメモリー中の特定のオフセットにロードする役割を担っています。通常、vmlinux.ldsは、以下のようなコードになります。

リスト2. 一般的なvmlinux.ldsファイル
 OUTPUT_ARCH(<arch>)     	/* <arch> includes architecture type */ 
 ENTRY(stext)            	/* stext is the kernel entry point */ 
 SECTIONS                	/* SECTIONS command describes the layout
			 	   of the output file */ 
 { 
     .  = TEXTADDR;      	/* TEXTADDR is LMA for the kernel */ 
     .init : {     	 	/* Init code and data*/ 
              _stext = .;       /* First section is stext followed 
				   by __init data section */ 
              __init_begin = .; 
                     *(.text.init) 
              __init_end = .; 
             } 
     .text : {      	/* Real text segment follows __init_data section */ 
              _text = .; 
                     *(.text) 
              _etext = .;     	/* End of text section*/ 
             } 
     .data :{ 
              _data=.;        	/* Data section comes after text section */ 
                     *(.data) 
              _edata=.;  
             }                  /* Data section ends here */ 
     .bss : {                   /* BSS section follows symbol table section */ 
              __bss_start = .; 
                     *(.bss) 
              _end = . ;      	/* BSS section ends here */  
             } 
  }

LMA は、ロード・モジュール・アドレスで、カーネルがロードされることになるターゲットの仮想メモリー内のアドレスを意味します。TEXTADDR は、カーネルの仮想開始アドレスで、この値は、arch/<target>/ 下のMakefileに指定されます。このアドレスは、ブートローダーが使用するアドレスに一致しなければなりません。

ブートローダーがカーネルをフラッシュなりDRAMなりにコピーし終わったら、カーネルは、(通常はDRAM中の)TEXTADDR に再配置されます。そうしておいて、ブートローダーは、このアドレスに制御を渡します。その結果、カーネルは実行を開始します。

パラメーターの渡し方とカーネルのブートアップ

stext はカーネルのエントリー・ポイントです。すなわち、このセクション下のコードが、カーネルのブートアップ時に最初に実行されるということです。この部分は、普通、アセンブリー言語で記述され、通常、カーネルのディレクトリーarch/<target>/ に置かれます。この部分のコードは、カーネル・ページ・ディレクトリーを設定し、識別カーネル・マッピングを作成し、アーキテクチャーやプロセッサーを識別し、start_kernel (システムの初期化を行うメインのルーチン) に分岐します。

start_kernel は、最初にsetup_arch を呼び出します。この部分で、アーキテクチャー固有のセットアップが行われます。そこでは、ハードウェア・レジスターの初期化、ルート・デバイスやシステムで利用可能なDRAMおよびフラッシュのサイズの認識、システムで利用可能なページ数の指定、ファイルシステムのサイズなどが行われます。これらの情報は、ブートローダーからカーネルにパラメーター形式で渡されます。

ブートローダーからカーネルへのパラメーターの渡し方には、parameter_structureとタグ・リストの2通りの方法があります。もちろん、param構造体は、個々のパラメーターをメモリー内のparam_structの特定のオフセットに置かなければならないという制約がある点で、難があります。最近のカーネルは、パラメーターをタグ・リストとして受けとる仕様になっており、パラメーターをタグ付きのフォーマットに変換するようになっています。param_struct は、include/asm/setup.h. で定義されています。主なフィールドは、以下のとおりです。

リスト3. parameter構造体のサンプル
 struct param_struct  { 
  unsigned long page_size;     /* 0:  Size of the page  */ 
  unsigned long nr_pages;      /* 4:  Number of pages in the system */ 
  unsigned long ramdisk        /* 8: ramdisk size */ 
  unsigned long rootdev;       /* 16: Number representing the root device */ 
  unsigned long initrd_start;  /* 64: starting address of initial ramdisk */
	                                  /* This can be either in flash/dram */ 
  unsigned long initrd_size;   /* 68: size of initial ramdisk */ 
 }

ここで、数字は、フィールドの定義を行うparam構造体の中のオフセットを表しています。つまり、ブートローダーがparameter構造体をアドレス0xc0000100に配置したとすると、パラメーターrootdevは0xc0000100 + 16に、initrd_startは0xc0000100 + 64に、などと配置されることになります。そうしないと、カーネルは、パラメーターを正しく認識できなくなります。

上で触れたように、2.4.xシリーズのカーネルのほとんどは、ブートローダーからカーネルにパラメーターを渡す際の制約から、パラメーターをタグ付きのリスト・フォーマットで受けとる仕様になっています。タグ付きリストの場合、各タグは、引き渡されるパラメーターを識別するためのtag_headerの後に、そのパラメーターに対する値を続ける形式になっています。タグ・リストでのタグの一般的なフォーマットは、以下のようなものとなります。

リスト4. タグ・フォーマットのサンプル。カーネルは、各タグを <ATAG_TAGNAME> ヘッダーで識別する。
 #define <aTAG_TAGNAME>  <Some Magic number> 

 struct <tag_tagname> { 
         u32 <tag_param>; 
         u32 <tag_param>; 
 }; 

 /* Example tag for passing memory information */ 

 #define ATAG_MEM        0x54410002  /* Magic number */ 

 struct tag_mem32 { 
         u32     size;               /* size of memory */ 
         u32     start;              /* physical start address of memory*/ 
 };

setup_arch も、フラッシュ・バンクやシステム・レジスターなどのデバイスでメモリー・マッピングが必要なら、それを行う必要があります。アーキテクチャー固有の設定が終了したら、制御はstart_kernel関数に戻り、そこでシステムの残りの部分の初期化が行われます。残りの初期化作業には、以下のようなものがあります。

  • トラップの設定
  • 割り込みの初期化
  • タイマーの初期化
  • コンソールの初期化
  • mem_init の呼び出し。mem_init は、いろいろなゾーンや上位アドレス・メモリーなどのページ数を計算します
  • スラブ・アロケーターの初期化とVFS、バッファー・キャッシュなどのスラブ・キャッシュの作成
  • proc、ext2、JFFS2など各種ファイルシステムのセットアップ
  • ファイルシステムのinitコマンドを実行し、loginプロンプトを表示するkernel_thread の作成initプログラムが /bin、/sbin、/etcのいずれにもなければ、ファイルシステムの /binにあるシェルを実行します。

デバイス・ドライバー

組み込みシステムには、通常、タッチスクリーン、キーパッド、ローラー・ホイール、センサー、RS232インターフェース、LCDなど、ユーザー入出力用にいろいろなデバイスが利用されます。これらの他にも、フラッシュ、USB、GSMなどなど、特殊なデバイスが数多く利用されます。カーネルは、これらのデバイスを、それぞれのデバイスに対応したデバイス・ドライバーを介して制御しますし、GUIなどのユーザー・アプリケーションも、デバイス・ドライバーを介して、それらのデバイスにアクセスします。以下では、通常ほとんどすべての組み込み環境で使用されるようないくつかの重要なデバイスのデバイス・ドライバーに注目してみたいと思います。

フレームバッファー・ドライバー

このドライバーは、非常に重要なものです。というのは、システム画面は、このドライバーを介して表示されるからです。フレームバッファー・ドライバーは、通常、3つの階層からなっています。一番下の層は、基本的なコンソール・ドライバーdrivers/char/console.cで、テキスト・コンソール用の汎用的なインターフェース部分が提供されます。コンソール・ドライバーの機能を使用することで、画面にテキストを表示することができます。しかし、絵や動画の表示は行えません (それには、ビデオ・モード機能が必要であり、通常、この機能は中位層、すなわちdrivers/video/fbcon.cに置かれます)。この2つ目のドライバーでは、ビデオ・モードでの描画のための汎用的なインターフェースが提供されます。

フレームバッファーとは、ビデオ・カード上のメモリーのことで、ユーザー空間上にメモリー・マップする必要があります。そうすることで、絵やテキストをこのメモリー・セグメントに書き込むことが可能になります。このメモリーに書き込まれたものは、画面上に映し出されます。フレームバッファーのサポートによって、描画についても、全体的な性能についても、速度が向上します。この点に関しては、最上位層のドライバーも大きくかかわってくるところです。最上位層は、ハードウェアに非常に依存するドライバーで、ビデオ・カード・コントローラー、サポートされているデプスやモード、パレットといったものを有効または無効にするなど、ビデオ・カードのいろいろなハードウェアの機能をサポートする必要のある部分です。ビデオの機能を正しく実現する上で、これら3つの層は相互に依存する関係にあります。フレーム・バッファーに関係付けられるデバイスは、/dev/fb0 (メジャー番号29、マイナー番号0) です。

入力デバイス・ドライバー

組み込みデバイスでもっとも基本的なユーザー入出力デバイスに、タッチ・パネルがあります。その他、キーパッド、センサー、ローラー・ホイールも、いろいろな用途で数多くのデバイスに採用されています。

タッチ・パネルの主な機能は、ユーザーがパネルに指を触れたことを随時報告し、その接触位置の座標を明らかにすることにあります。これは、一般に、接触があったときに、割り込みを発生することで実現されます。

その際のデバイス・ドライバーの役割は、割り込みが発生したときに、タッチ・パネルのコントローラーに問い合わせを行い、接触位置の座標を送信するようにコントローラーに求めることです。ドライバーは、座標を受信すると、接触があったことおよびデータが用意されていることをユーザー・アプリケーションにシグナルし、(可能であれば) データをアプリケーションに送信します。ユーザー・アプリケーションは、自身の必要性にしたがって、そのデータを処理します。

キーパッドを含め、ほとんどすべての入力デバイスが、同様の原理で機能を果たします。

フラッシュMTDドライバー

MTDデバイスとは、フラッシュ・チップ、コンパクト・フラッシュ・カード、メモリー・スティックなどのような種類のデバイスのことで、ますます組み込みデバイスに利用されるようになってきています。

MTDドライバーは、Linuxで、とくに組み込み環境用として開発されてきている新しいクラスのドライバーです。従来のブロック・デバイス・ドライバーと比較してMTDドライバーを利用することの主な利点は、MTDドライバーがとくにフラッシュ・ベースのデバイス用として設計されている点です。したがって、セクター単位の消去や読み書きに関して、サポートや管理やインターフェースが従来よりも良くなっています。LinuxのMTDドライバーのインターフェースは、ユーザー・モジュールとハードウェア・モジュールの2つのモジュールに分けられます。

ユーザー・モジュール
これらのモジュールは、ユーザー空間から直接利用可能なインターフェースを提供します。すなわちキャラクターの直接アクセス、ブロックの直接アクセス、FTL (Flash Transition Layer -- フラッシュで使用される1種のファイルシステム)、JFS (Journaled File System -- ブロック・デバイスをエミュレートするのではなく、フラッシュ上で直接ファイルシステムをサポートする) といったインターフェースです。フラッシュ上でのJFSの現在のバージョンはJFFS2です (これについては、後述)。

ハードウェア・モジュール
これらのモジュールは、メモリー・デバイスへの物理的なアクセスを可能にするもので、直接使用されることはありません。ハードウェア・モジュールは、上記のユーザー・モジュールを介してアクセスされます。フラッシュでの読み出し、消去、書き込みを行うための実際のルーチンが用意されます。

MTDドライバーのセットアップ
あるフラッシュ・デバイスにアクセスし、その上にファイルシステムを設けたい場合、MTDサブシステムをカーネルに含める形でコンパイルする必要があります。それには、適当なMTDハードウェアとユーザー・モジュールを選択します。MTDサブシステムは、現在でも、さまざまな種類のフラッシュ・デバイスをサポートしていますが、いろいろなフラッシュ・チップに対応したドライバーが次々と出されてきています。

フラッシュへのアクセスを可能にするユーザー・モジュールとして人気のあるものに、MTD_CHARMTD_BLOCK の2つがあります。

MTD_CHAR には、フラッシュのキャラクタを直接アクセスする機能があるのに対して、MTD_BLOCK は、フラッシュを通常の (IDEディスクのような) ブロック・デバイスとして取り扱い、その上にファイルシステムを作成できるようにしています。MTD_CHAR に関係付けられるデバイスは /dev/mtd0、mtd1、mtd2 (など) で、MTD_BLOCK に関係付けられるデバイスは /dev/mtdblock0、mtdblock1 (など) です。MTD_BLOCK デバイスは、ブロック・デバイスに似せたエミュレーションを行いますので、多くの場合、このエミュレーションの上にFTLやJFFS2のようなファイルシステムを作成すればよいでしょう。

このためには、フラッシュ・デバイスを、ブートローダー部、カーネル部、ファイルシステム部に分けるためのパーティション・テーブルを作成する必要が出てくるでしょう。パーティション・テーブルのサンプルを示すとすれば、以下のような情報が含まれることになるでしょう。

リスト5. MTD対応の簡単なフラッシュ・デバイス・パーティション
 struct mtd_partition sample_partition = { 
      { 
                                           /* First partition */ 
            name : bootloader,             /* Bootloader section */ 
            size    : 0x00010000,          /* Size  */ 
            offset  : 0,          /* Offset from start of flash- location 0x0*/  
            mask_flags : MTD_WRITEABLE     /* This partition is not writable */ 
      },  
      {                                    /* Second partition */ 
            name : Kernel,                 /* Kernel section */ 
            size    :  0x00100000,         /* Size */ 
            offset : MTDPART_OFS_APPEND,   /* Append after bootloader section */ 
            mask_flags : MTD_WRITEABLE     /* This partition is not writable */ 
      },  
      {                                    /* Third partition */ 
            name : JFFS2,                  /* JFFS2 filesystem */ 
            size    :  MTDPART_SIZ_FULL,   /* Occupy rest of flash */ 
            offset :  MTDPART_OFS_APPEND   /* Append after kernel section */ 
      }
 }

上のパーティション・テーブルでは、MTD_BLOCK インターフェースを使って、フラッシュ・デバイスの分割を行っています。これらのパーティションのデバイス・ノードは、以下のとおりです。

上の簡単なフラッシュ・パーティションのデバイス・ノード
  User          device node             Major number    Minor number
  Bootloader    /dev/mtdblock0          31              0
  Kernel        /dev/mtdblock1          31              1
  Filesystem    /dev/mtdblock2          31              2

この場合、ブートローダーは、ルート・デバイス・ノード (/dev/mtdblock2) やファイルシステムの存在するフラッシュ内のアドレス (この場合、FLASH_BASE_ADDRESS + 0x04000000) に関して、正確なパラメーターをカーネルに渡す必要があります。分割が完了すると、フラッシュ・デバイスは、ファイルシステムをロードしたりマウントする準備ができたことになります。

LinuxにおけるMTDサブシステムの一番の目的は、ハードウェア・ドライバーとシステムの上位層であるユーザー・モジュールの間に、汎用的なインターフェースを設けることにあります。ハードウェア・ドライバーは、JFFS2やFTLのようなユーザー・モジュールが使用している手法について知る必要はありません。ハードウェア・ドライバーが提供すべきことは、基盤となっているフラッシュ・システムに対してreadwrite、およびerase の操作を行うための1組の単純なルーチンを提供することだけです。


組み込みデバイスのファイルシステム

システムは、構造化されたフォーマットの情報を格納したり取り出したりするための方法を必要とします。それが、ファイルシステムが必要となる由縁です。Ramdisk (参考文献参照) は、コンピューターのRAMをデバイスとして使用しながらファイルシステムを作成したりマウントするためのメカニズムで、通常はディスクのないシステム (もちろん、永続的な記憶のためのメディアとしてフラッシュ・チップしか持たない小さな組み込みデバイスもその中に含まれる) で使用されます。

ユーザーは、信頼性や堅牢性や拡張機能などの必要性に応じて、ファイルシステムの種類を選択することができます。以下では、このときの選択肢をいくつか紹介し、それぞれの利点、欠点を示したいと思います。

The second Extended Filesystem (Ext2fs)

Ext2fsは、それ以前のファイルシステムExtended File System (Extfs) を駆逐し、現在ではLinuxの事実上の標準となっています。Extfsは、最大2 Gバイトまでのファイル・サイズと最大255文字までのファイル名をサポートしていましたが、inode (データ修正タイムスタンプを含めて) はサポートしていませんでした。Ext2fsには、大幅な改良が加えられています。以下のような利点を備えています。

  • Ext2fsは、最大4テラバイトまでのメモリーをサポートする。
  • Ext2fsのファイル名の長さは、最大1012文字までである。
  • ファイルシステムを作成するときに、管理者が論理ブロックのサイズを選択できる (一般的なサイズは1024、2048、4096バイト)。
  • Ext2fsは、高速な記号リンクを実装する。この目的でデータ・ブロックを割り当てる必要はなく、ターゲット名はinodeテーブルに直接格納される。これによって、性能を、とくに速度を向上させている。

その安定性、信頼性、堅牢性のゆえに、Ext2ファイルシステムは、デスクトップ、サーバー、ワークステーション、さらには一部の組み込みデバイスなど、Linuxベースのほとんどすべてのシステムに採用されています。ただし、組み込みデバイスでということになると、Ext2fsには欠点もいくつかあります。

  • Ext2fsは、IDEデバイスのようなブロック・デバイス用として設計されており、論理ブロックのサイズは512バイトとか1 Kバイトといった単位になる。この点、セクター・サイズがまちまちなフラッシュ・デバイスには不向きである。
  • Ext2ファイルシステムでは、セクター・ベースの消去 / 書き込みの管理がうまくできない。Ext2fsでどこかのセクターの中の1バイトを消去しようとすると、セクター全体をRAMにコピーしてきて、消去を行い、再書き込みを行う必要がある。フラッシュ・デバイスには消去寿命 (約10万回の消去) というものがあり、その後はデバイスが使用できなくなることを考えれば、これが適当な方法だとはいえない。
  • Ext2fsは、停電の場合のクラッシュ保護を行っていない。
  • Ext2ファイルシステムは、磨耗平均化をサポートしていないため、セクター / フラッシュの寿命を短縮することにつながる。(磨耗平均化を行い、書き込みや消去に代わるがわる別々のアドレス領域を使用するようにすると、フラッシュの寿命を延長することができる。)
  • Ext2fsは特段優れたセクター管理を行っているわけではないので、ブロック・ドライバーの設計が極めて難しいものになる。

このような理由から、組み込み環境では、通常Ext2fsよりもMTD/JFFS2の組み合わせのほうが、よく利用されています。

RamdiskへのExt2fsのマウント
Ramdiskの考え方にしたがえば、Ext2ファイルシステムを (あるいは、どんなファイルシステムでも) 組み込みデバイス上に作成しマウントすることができます。

リスト6. 簡単なExt2fsベースのRamdiskの作成
  mke2fs -vm0 /dev/ram 4096
  mount -t ext2 /dev/ram /mnt
  cd /mnt
  cp /bin, /sbin, /etc, /dev ... files in mnt
  cd ../
  umount /mnt
  dd if=/dev/ram bs=1k count=4096 of=ext2ramdisk

mke2fs は、ext2ファイルシステムを作成するためのユーティリティーで、スーパー・ブロック、一連のinode、inodeテーブルなどをどんなデバイスにでも作成することができます。

上の例では、/dev/ram が4096ブロックからなるext2ファイルシステムの構築されるデバイスです。ここでは、このデバイス (/dev/ram) が/mnt という名前の一時的なディレクトリー上にマウントされ、必要なファイルすべてがコピーされています。これらのファイルのコピーが終わると、ファイルシステムがアンマウントされ、デバイス (/dev/ram) の内容が1個のファイル (ext2ramdisk) にダンプされます。このファイルが、求められているRamdisk (Ext2ファイルシステム) です。

上の手順では、4 MバイトのRamdiskを作成し、必要なファイル・ユーティリティーを使ってRamdiskへの書き込みを行っています。

Ramdiskに含めるべき重要なディレクトリーには、以下のようなものがあります。

  • /bin --initbusyboxshell、ファイル管理ユーティリティーなど、ほとんどのバイナリー・ファイルを入れておきます。
  • /dev -- デバイスで使用されるすべてのデバイス・ノードを入れます。
  • /etc -- システムが使用するすべてのコンフィギュレーション・ファイルを入れます。
  • /lib -- libc、libdlなど、必要なすべてのライブラリーを入れます。

Journaling Flash File Systemバージョン2 (JFFS2)

JFFSは、もともと、スウェーデンのAxis Communicationsが開発したもので、Red HatのDavid Woodhouse氏によって改良が加えられました。第2バージョンのJFFS2は、小型の組み込みデバイス用のフラッシュ・チップを直接扱うためのファイルシステムとして事実上の標準になりつつあります。JFFS2ファイルシステムは、ログ構造化されています。つまり、基本的に、長いノード・リストだということです。各ノードは、ファイルに属している情報をいろいろと含んでいます。たとえば、ファイルの名前とか、ある程度のデータなどです。以下のような利点 があることから、JFFS2は、ディスクを使用しない組み込みデバイス用として、徐々にExt2fsにとって代わりつつあります。

  • JFFS2は、フラッシュ消去 / 書き込み/ 読み出しをセクター・レベルで行う点で、Ext2ファイルシステムよりも優れている。
  • JFFS2は、クラッシュ / 電源断時の保護機能がExt2fsよりも優れている。データのごく一部を変更したいときでも、Ext2ファイルシステムは、セクター全体をメモリー (DRAM) にコピーしてきて、メモリー内で新しいデータとのマージを行い、セクター全体を書き戻すといったことを行います。このことは、1ワードを変更する場合でも、セクター全体 (64 Kバイト) を対象としてread/erase/writeルーチンを実行しなければならないことを意味します。したがって、非常に非効率的です。DRAM内でデータをマージしている最中に停電などの災難が起こったとすると、フラッシュのそのセクターは、データをDRAMに読み出した後に消去されますので、データ・ブロック全体が失われてしまうことになります。JFFS2は、セクター全体の書き換えを行うのではなく、ファイルをアペンドします。また、クラッシュ / 電源断時保護機能も備えています。
  • それに、おそらく最も重要な点は、JFFS2がフラッシュ・チップなどの組み込みデバイス向けに作成されたもので、その全体的な設計がフラッシュの管理に優れて適しているということです。

もともとフラッシュ・デバイス用に開発されていますので、組み込み環境でJFFS2を使うことの欠点は、あまりありません。

  • JFFS2は、ファイルシステムが満杯かそれに近い状態になると、かなり処理が遅くなりやすい。これは、ガーベッジ・コレクションの問題から来るものです (詳しくは、参考文献参照)。

JFFS2ファイルシステムの作成
Linux下でJFFS2ファイルシステム (基本的にはJFFS2を使用したRamdisk) を作成するには、mkfs.jffs2 コマンドを使用します。

リスト7. JFFS2ファイルシステムの作成
 mkdir jffsfile 
 cd jffsfile 

 /* copy all the /bin, /etc, /usr/bin, /sbin/ binaries and /dev entries 
that are needed for the filesystem here */ 

 /* Type the following command under jffsfile directory to create the JFFS2 Image */ 

 ./mkfs.jffs2 -e 0x40000 -p -o ../jffs.image

上の例は、mkfs.jffs2の通常の使い方を示しています。-e オプションでは、フラッシュの消去セクター・サイズ (通常は、64 Kバイト) を指定します。-p オプションは、イメージ内の残りのスペースをゼロで埋めたいときに使用します。-o オプションは、出力ファイルの指定に使用されます。このファイルが、通常、JFFS2ファイルシステムのイメージとなるもので、上ではjffs.imageとしています。JFFS2ファイルシステムを作成したら、フラッシュ内の適当な位置 (ファイルシステムを探すときのための情報としてブートローダーがカーネルに通知するアドレス) にそれをロードし、カーネルがファイルシステムをマウントできるようにします。

tmpfs

組み込みデバイスが完全に機能するようになり、その上でLinuxを実行できるようになったら、バックグラウンドでたくさんのデーモンが実行され、たくさんのログ・メッセージが作成されるようになります。また、syslogd、dmesg、klogdなど、カーネルのすべてのログ作成メカニズムが /varや /tmpといったディレクトリーにたくさんのメッセージを作成します。これらのプロセスによって大量のデータが生成されますので、これらすべての書き込みをフラッシュに対して行うことはお薦めできません。これらのメッセージは、次のリブートを行うまで保存しておく必要はありませんので、この問題は、tmpfsを使って解決することができます。

tmpfsは、ただただシステムに対する不要なフラッシュ書き込みを減らすためだけに使用されるメモリー・ベースのファイルシステムです。tmpfsはRAM内に置かれますので、書き込み / 読み出し / 消去の動作は、フラッシュではなくRAMの中で行われます。したがって、ログ・メッセージは、フラッシュではなくRAMに書き込まれ、次回のリブートまで保存されることはありません。tmpfsは、また、記憶領域としてディスク・スワップ・スペースを利用し、ファイル保存のためのページ要求の際も、仮想メモリ (VM) サブシステムを利用します。

tmpfsには、以下のような利点があります。

  • ファイルシステムのサイズが動的 -- コピーしたり、新規に作成したり、削除したりした結果のファイルやディレクトリーの数にしたがって、ファイルシステムのサイズは、小さくなったり大きくなったりします。したがって、メモリが最適に利用されることになります。
  • 速度 -- tmpfsはRAMに置かれますので、読み書きはほとんど瞬時に行われます。さらに、ファイルがスワップに保存されている場合には、I/O動作は非常に高速になります。

tmpfsの欠点は、システム・リブート時にすべてのデータが失われてしまうことです。したがって、重要なデータをtmpfsに保存することはできません。

tmpfsのマウント
Ext2fsやJFFS2など他のほとんどのファイルシステムが、基盤となるブロック・デバイスの上に置かれるのと異なり、tmpfsはVMの上に直接設定されます。したがって、tmpfsファイルシステムのマウントは、たやすい問題です。

リスト8. tmpfsのマウント
/* Entries in /etc/rc.d/rc.sysinit for creating/using tmpfs */ 

 # mount -t tmpfs tmpfs /var -o size=512k 
 # mkdir -p /var/tmp 
 # mkdir -p /var/log 
 # ln -s /var/tmp /tmp

これらのコマンドによって、/var上にtmpfsが作成され、tmpfsの最大サイズが512 Kに制限されます。また、tmp/ とlog/ のディレクトリーがtmpfsの一部として作成され、ログ・メッセージがRAMに保存されるようにされます。

tmpfsのエントリーを /etc/fstabに加えたいのであれば、以下のようにすればよいでしょう。

tmpfs /var tmpfs size=32m 0 0

これで、新しいtmpfsファイルシステムが /varにマウントされます。


グラフィカル・ユーザー・インターフェース (GUI) の選択肢

ユーザーの立場からすれば、システムの中で最も重要なのがグラフィカル・ユーザー・インターフェース (GUI) です。ユーザーは、GUIを通してシステムとやりとりを行うわけですので。したがって、GUIは使いやすく、すごく信頼性の高いものでなければなりません。しかし一方で、メモリーに制約のある小型の組み込みデバイスでGUIをスムーズに実行するためには、そのメモリーの使い方にも配慮が必要です。そのため、GUIは処理が軽く、非常に高速にロードできるものでなければなりません。

もう一つの重要な点は、ライセンスが絡んでくるという問題です。GUIのディストリビューションによっては、商業用でも無料で使用できるようにするためにライセンスを必要とするものもあります。また、GUIを事業の中で利用する場合には、使用料を払わなければならないものもあります。

結局のところ、ほとんどの開発者は、おそらくXFree86を選択することになるでしょう。なぜならば、XFree86が好みのツールの使える慣れ親しんだ環境を提供するからです。しかし、Century SoftwareのMicrowindows (Nano-X) とかTrolltechのQT/Embeddedなど、最近のGUI製品は、主に、サイズが小さい、実行速度が速い、カスタム・ウィジェットをサポートしている、といった理由から、組み込みLinuxの分野で大健闘しています。

以下では、これら個々の製品に目を向けてみましょう。

Xfree86 4.X (フレームバッファー対応のX11R6.4)

XFree86 Project, Inc. は、自由に再配布可能なオープン・ソースのX Window SystemであるXFree86を製品化している団体です。X Window System (X11) は、アプリケーションがグラフィックスを利用して表示を行えるようにするための各種リソースを提供するもので、UNIXおよびUNIX系のシステムで最も一般的に使用されるウィンドウ型システムです。X Window Systemは、小ぶりで効率がよく、幅広いハードウェアをサポートし、ネットワーク透過で、文書化もしっかりなされています。X11は、ウィンドウ管理、イベント処理、同期化、クライアント間通信などに強力な機能を用意していますし、そのAPIは、すでにほとんどの開発者によく知れわたっています。また、カーネルのフレームバッファーをサポートする機能を内蔵し、非常にサイズが小さいため、メモリーの少ないデバイス向けに非常に有用です。X Serverは、VGAや 非VGAグラフィック・カードをサポートし、デプスも1、2、4、8、16、32をサポートし、レンダリング・サポートも内蔵しています。最新バージョンは、XFree86 4.1.0です。

XFree86の利点は、以下のとおりです。

  • フレームバッファー・アーキテクチャーを採用しており、速度面で性能を高めている。
  • 比較的サイズが小さい。サイズは600~700 Kバイトの範囲で、小さいデバイスでやすやすと実行が可能である。
  • サポートが非常に良い。さまざまな文書がオンラインで入手でき、XFree86開発専門のメーリング・リストも多数存在する。
  • XのAPIは、非常に広範囲にわたっている。

欠点としては、以下のことがあります。

  • 組み込みGUIウェアとして世の中に出まわっている最新の製品に比べれば、速度面で性能が劣っている。
  • やはりNano-XとかQT/EmbeddedなどのGUIの最新の動きと比べた場合、これらの製品がとくに組み込み環境向けに設計されているため、XFree86のほうが必要なメモリー量が多いようである。

Microwindows

Microwindowsは、Century Softwareのオープン・ソースのプロジェクトで、小さな表示装置を備えた小型デバイス向けに設計されたシステムです。最近のグラフィカルなウィンドウ型環境を目指したさまざまな機能を搭載しています。Xと同様、Microwindowsも、いろいろなプラットフォームでサポートされています。

Microwindowsのアーキテクチャーは、クライアント / サーバー・ベースで、階層型設計になっています。最下層には、画面および入力装置 (キーボードやマウスなど) のドライバーが位置し、実際のハードウェアとのやりとりを行います。中間層には、ポータブルなグラフィックス・エンジンが位置し、線描、領域塗りつぶし、多角形、クリッピング、カラー・モデルをサポートします。

Microwindowsは、最上位の層で2つのAPIをサポートします。MicrowindowsといわれるWin32/WinCE API実装とNano-Xとして知られているほぼGDKのAPIに似た別のAPIの2つです。Nano-Xは、Linuxに採用されています。これは、サイズの小さなアプリケーション用に作られたX系のAPIです。

Microwindowsは、1、2、4、または8 bpp (ビット / ピクセル) のパレット表示および8、15、24、または32 bppのツルーカラー表示をサポートしています。Microwindowsは、また、フレームバッファーもサポートしており、非常に高速な表示を実現しています。Nano-Xサーバーのサイズは、だいたい100~150 Kバイト程度です。

Nano-Xアプリケーション自体の平均的なサイズは、30~60 Kバイトです。Nano-Xはメモリー・サイズに制約のあるローエンドのデバイス向けに設計されているため、Xのようなおびただしい数の関数をサポートしてはいませんので、Tiny X (Xfree86 4.1) を代替するものととして利用することはできません。

XではなくNano-X向けに修正を施したFLTK (Fast Light Toolkit) アプリケーション開発環境の1つのバージョンであるFLNXを、Microwindowsの上で実行することもできます。FLTKについては、本稿で後述します。

Nano-Xの利点は、以下のとおりです。

  • Xlibとは異なり、Nano-Xは、現時点でもクライアントごとに同期して実行されます。すなわち、クライアントからリクエスト・パケットが送信されると、サーバーはそのパケット全体が到着するまで待機し、別のクライアントに対してサービスを行うことはありません。これによって、サーバーのコードは格段に簡素なものになり、かつ実行も非常に高速です。
  • サイズが小さい

Nano-Xの欠点は、以下のとおりです。

  • ネットワークの機能が、まだうまく作り込まれていない (とくにネットワーク透過性の部分)。
  • 既製のアプリケーションが、まだそれほど用意されていない。
  • Xに比べ、Nano-Xは、それほど文書化やサポートが行われていない。ただ開発のほうは最近ものすごいスピードで進んでおり、この点も変化する可能性がある。

Microwindows上のFLTK API

FLTKは、シンプルながら柔軟性に富んだGUIツールキットで、いまLinuxの世界で、とくにサイズが小さくなければならない環境で注目を集めつつあります。FLTKは、ボタン、ダイアログボックス、テキストボックス、あるいは豊富な種類の「バリュエーター (valuators)」(数値の入力に使用されるウィジェット) など、GUIツールキットに期待されるほとんどのウィジェットを用意しています。他にも、スライダー、スクロールバー、ダイアルなどがあります。

Microwindows GUIエンジン向けのFLTKのLinuxバージョンがFLNXと呼ばれているものです。Fl_WidgetとFLUIDの2つのコンポーネントからなっています。Fl_Widgetは、すべての基本的なウィジェットAPIで構成されます。FLUID (Fast Light User Interface Designer) は、FLTKのソース・コードを生成するためのグラフィック・エディターです。全体として、FLNXは、組み込み環境向けのアプリケーションを作成するための素晴らしいUIビルダーとなっています。

Fl_Widgetのサイズは約40~48 Kバイト、FLUIDは (ウィジェットをすべて含めて) 約380 Kバイトです。このようにサイズが非常に小さいことから、Fl_WidgetとFLUIDは、組み込み開発の世界で非常に人気のあるものになっています。

利点は、以下のとおりです。

  • Windowsなど、もっと確立された環境でGUIベースのアプリケーションを開発することに慣れた人なら、FLTK環境にすぐに慣れる。
  • 文書も、完全でよく書かれたマニュアルが用意されている。
  • LGPLを通して配布されるため、開発者が自分のアプリケーションのライセンス供与を行う場合、柔軟な対応ができる。
  • FLTKはC++ のライブラリである (PerlやPythonとのバインドも可能)。最近のほとんどのGUI環境がオブジェクト指向なので、オブジェクト指向モデルの選択は、望ましい選択である。この結果、同じようなAPIを使って開発されたアプリケーションの移植も容易になるはずである。
  • Centuryの環境には、ScreenTopやViewMLブラウザーなど、便利な機能が多数用意されている。

欠点は、以下のとおり。

  • 純粋なFLTKでは、XとWindowsの両方のAPIを扱うことができるが、FLNXはそれができない。Xとの非互換性が、いろいろな製品への採用の妨げになっている。

Qt/Embedded

Qt/Embeddedは、Trolltechの新しい組み込みLinux向けグラフィカル・ユーザ・インターフェース・システムです。Trolltechは、最初、QtをLinuxデスクトップ向けにクロス・プラットフォームの開発ツールとして製品化しました。Qtは、Microsoft WindowsとともにUNIX系のさまざまな製品をサポートしています。最も人気のあるLinux用デスクトップ環境の一つであるKDEも、Qtを使って開発されたものです。

Qt/Embeddedは、もともとのQtをベースにして、組み込み環境向けにいろいろな微調整を施したものです。Qt Embeddedは、Qt APIを介してLinuxのI/O機能と直接やりとりを行います。オブジェクト指向プログラミングに精通し、なじんでいるプログラマーにとっては、理想的な環境なのではないでしょうか。また、オブジェクト指向アーキテクチャーを採用しているため、コードも構造化され、再利用可能で高速なものとなります。Qt GUIは、他のGUIに比べ非常に高速であり、また階層化を行っていないため、Qt/Embeddedは、Qtベースのプログラムを実行する上で最もコンパクトな環境となっています。

Trolltechは、一般にQpeと呼ばれているQt Palmtop Environmentの製品化も行っています。Qpeは、基本的なデスクトップ・ウィンドウであり、その環境は、開発用として使いやすいインターフェースを提供しています。Qpeには、個人情報管理 (Personal Information Management: PIM) アプリケーション、Internetクライアント、ユーティリティーなどがひととおり用意されています。ただし、Qt/EmbeddedやQpeを製品に組み込む場合は、Trolltechから商用ライセンスを取得する必要があります。(基となるQtは、バージョン2.2以降のものがGPLで入手できます。)

利点:

  • オブジェクト指向アーキテクチャーを採用し、高速な実行に寄与している
  • サイズが小さい。約800 K
  • アンチエイリアス処理されたテキストおよびアルファ・ブレンドされたピックスマップ

欠点:

  • Qt/EmbeddedおよびQpeは、商用ライセンス版のみの販売となっている

まとめ

組み込みLinux開発は、急速に進化しつつあります。開発者のみなさんは、ブートローダーやディストリビューションからファイルシステムやGUIまで、すべてについて、いろいろな選択肢を比較検討し、その中から選択を行う必要があります。といっても、このように自由に選択が可能であり、Linux社会も非常に活発であることから、Linuxでの組み込み開発には新しい展望が開けてきており、みなさんの仕様に合わせてモジュールを作り上げていくことが以前にもまして簡単になってきています。この結果、数多くの新しいハンドヘルド・デバイスや小型デバイスがオープンな製品として出現してきています。これは、非常にすばらしいことで、実際、もはや専門家でなくても、これらのモジュールの中から選択を行い、自分の必要性や望みに合わせてデバイスを作り上げることができます。

組み込みLinuxに関するこの入門記事が、みなさんの実験意欲を刺激し、自分の好みに合わせて小型のデバイスを手直ししてみようと思わせたとすれば幸いです。みなさんの開発のお役に立てるよう、以下に参考文献を紹介しておきます。この記事で紹介した技術についてさらに詳しい情報を知りたい方は、リンクを辿ってみてください。

参考文献

  • vmlinuxとzimageの違いについては、Alessandro Rubini著のKernel Configuration: dealing with the unexpected (Linux Magazine) の "Booting your kernel" のセクションをスクロール・ダウンしてみてください。すばらしい説明を読むことができます。
ツールチェーン:
  • The Wiki toolchain page には、本稿で紹介した3つのツールチェーンへのリンク (およびコメント) があります。
デバイス・ドライバー:
  • The Memory Technology Device (MTD) Subsystem for Linux は、メモリー・デバイス (とくにフラッシュ・デバイス) のドライバーを簡単に開発するための情報が掲載されています。
  • The Linux MTD, JFFS HOWTO (Vipin Malik著) には、MTDとJFFS2をうまく連携させるための方法が紹介されています。
  • 入門記事Linux device drivers で、Linuxデバイス・ドライバーのことが簡単に理解できます (Penguin Magazine)。
  • Linuxのデバイス・ドライバーについて、もっと理解を深めたい方は、O'Reilly著 「Linux Device Drivers, 2nd Edition」 を紐解かれるとよいでしょう。
  • BinutilsGCCGlibc は、すべて、Free Software Foundationからダウンロードできます。
  • NetWinderプラットフォームでの開発専門のボランティア・サイトNetwinder.orgに、数多くの便利なダウンロード品が用意されています。
  • Ramdiskのことなら、Mark NielsenのHow to use a Ramdisk for Linux にすばらしい解説があります。
  • FLNX は、FLTK (The Fast Light Toolkit) をベースにしています。
  • General Public License、略してGPL は、ソフトウェアをコピー、配布、修正するユーザーの権利を保証するものです。
  • ARM Linux は、ARMプロセッサー用Linuxについて知りたいことをすべて紹介しているすごいサイトです。ARMの製作者Russell King氏が管理しています。
  • Penguinppc.org は、PowerPCプロセッサー・ファミリー用Linuxの本拠です。このサイトには、PPCベースのアーキテクチャー向けにツールチェーンをセットアップする方法について、非常にためになるチュートリアルが掲載されています。
  • Silicon Penguinは、組み込みLinuxに関するリソースを網羅的に集めたリスト・サイトです。
  • ARMLinux - the book は、Aleph Oneから入手できます。本として注文もできますし、オンラインで読むこともできます。
  • The Embedded Linux Consortium は、組み込みLinuxスペースでの個人の開発者の活動としての入会を歓迎する非営利互助協会です。
  • IBMのLinux腕時計は、Linuxで動かしている小型組み込みデバイスの例です。これには、この記事の執筆者の一人Vishal Kulkarniも関係しました。Linux腕時計については、this article (FreeOS.com、2001年3月号) にも紹介されています。
  • developerWorks に掲載されているその他のLinux参考文献もご覧ください。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux
ArticleID=287115
ArticleTitle=組み込みデバイスでのLinuxシステム開発
publish-date=03012002