1.PC-UNIXの普及と従来型パッケージの限界

 10年前には,LinuxをはじめとするPC-UNIXが一般社会にこれだけ普及するとは誰も予想できませんでした.オープンソース運動の追い風を受けながら,PC-UNIXはこの数年間でサーバ,ネットワーク,組み込み機器と,そのターゲットを着実に広げつつあります.

 それでは,この発展を通じてPC-UNIXに対する技術者の理解は進んだのでしょうか? 残念なことですが,筆者は技術者とPC-UNIXの間のギャップはますます広まっているのではないかと感じています.もちろん,中にはBSDやLinuxを自分の手足のごとく使いこなせる読者も大勢いることと思いますが,そのようなケースは稀であり,ディストリビュータが配布している内容を,若干カスタマイズして利用するような場合がほとんどではないでしょうか?

 デスクトップ環境のように数十Gバイトのハードディスク,数百MバイトのRAMなど膨大なリソースを利用できる場合は良いのですが,組み込み機器のように数百Kバイト単位でメモリ資源を節約する必要がある場合には,「若干のカスタマイズ」程度では完全にお手上げ状態となってしまいます.この問題を解決するために,最近では各社からLinux環境をターゲット機器向けに最適化・最小化するための専用ツールが販売されています.しかし,これら最適化ツールの整備状況はいまだ発展途上段階であり,先ほどの“ディストリビュータパッケージへの依存”という図式から脱却できるわけでもありません.

 それでは,技術者自らが,独自の組み込み機器専用のオリジナルディストリビューションを作成することは不可能なのでしょうか? これが今回の特集のテーマです.

2.Linuxの理解をはばむもの

 本特集では,数あるPC-UNIXの中から,対象としてLinuxを取り上げます.もはや世界を制覇した感のあるLinuxですが,その実体の理解は遅々として進んでいないように思えます.一体何が,Linuxの理解をはばむ原因になっているのでしょうか? まずは,この問題について考えてみましょう.

 一口にLinuxといいますが,その全体像はなかなか複雑です.中心にLinuxカーネルが位置しているのは言うまでもありませんが,カーネルだけではシステムは稼働しません.カーネルとは人間にたとえれば「魂,意識」であり,現世に関わるためには魂が宿る「肉体」が必要です.肉体とはコンピュータなのかという話になりそうですが,そう簡単にはいきません.

● ルートファイルシステムの重要性

 肉体の中でも,意識が宿るのは「中枢神経系」です.コンピュータ内部で中枢神経系に相当するものは何かといえば,これはCPUではなく「ファイルシステム」です.UNIXカーネルはファイルシステムがなければ,生存できません.ファイルはもとより,ハードディスクやコンソールなどのデバイスにアクセスするためにはファイルシステムを経由する必要があるからです.

 Linuxのインストールを経験された方であれば,「カーネルは起動したのだけれども,ルートファイルシステムがマウントできずにフリーズしてしまった」という経験をお持ちの方も多いと思います.これはまさに,カーネルとファイルシステムが不可分であることを示す好例です.従来,Linuxカーネルについては多くの解説書や記事が発表されてきたのですが,一方でルートファイルシステムは看過されて来たといっても過言ではありません.ルートファイルシステムの技術背景を正確に把握することが,Linuxを理解するための第一歩です.具体的なルートファイルシステムの構築方法については第4章で解説します.

● 標準Cライブラリによるシステムコールの隠蔽化と冗長性

 カーネルはファイルシステムを通して,手足を動かすようにファイルやデバイスを操作します.この指令は具体的にどのような方法で実現されているのでしょうか? 教科書的には,これらの操作は,open/read/write/closeなどの標準入出力関数を使うとされています.しかし,これも表面的な話で,その裏側ではシステムコールが暗躍しているのです.「ちょっと待て,私がもっている教科書にはopen/read/write/close自体がシステムコールであると記述されているぞ」と指摘される方もいらっしゃるでしょう.そのとおりなのですが,この状況がPC-UNIX学習者を混乱させる原因になっています.

 正確にいえば,私達がふだん利用しているopen/read/write/closeをはじめとする関数は,システムコールではなくライブラリ関数です.openという名前のライブラリ関数をソースの中で呼び出すと,内部でopenシステムコールを実行しているのです.システムコールを直接実行したつもりが,いつのまにか「ライブラリが介在」しているというわけです(図1).

〔図1〕
プログラム,ライブラリ,システムコールの関係

 この問題はプログラマが知らないうちに,開発しているプログラムが1Mバイト近いGNU C library(glibc)を背負い込んでしまうという事態に発展します.自分で記述したコードは1Kバイトにも満たないにもかかわらず,ターゲット機器に組み込もうとすると,合計1Mバイトのリソースをいきなり要求されるというわけです.ライブラリはまるで高利貸しのようですが,組み込みシステムを最適化するためには,この事実を冷静に見きわめなければなりません.システムコールとCライブラリの関係については,第1章で検討します.

● GNU開発ツールの運用情報の不足

 UNIX上でプログラム開発を行うための主役は何かと尋ねられたら,皆さんはどう答えられるでしょうか? 「gcc」という声が聞こえてきそうですが,残念ながらこれだけでは不十分です.たしかに,UNIX開発においてGNU Compiler Collection(GCC)が果たす役割は大きいのですが,先ほどのカーネル・ルートファイルシステムと同様に,Binary Utilities(binutils)という役者もまたGCCと不可分の関係にあります.

GCCは,与えられたCソースをCプリプロセッサ(cpp)で処理した後,Cコンパイラ(cc1)でアセンブリソースに変換するところまでを担当します.アセンブリソースのアセンブル,そしてオブジェクトファイルやライブラリのリンクは,binutilsパッケージ中のas,ldコマンドがそれぞれ実行します.

 このように,GCCとbinutilsはお互い密接に関連しながら,プログラム構築という一つの作業を分担しているのですが,その全体像はあまり知られていません(図2).しかも,一つ一つのツールに関する具体的な運用ノウハウがこれまで文書としてあまり配布されていません.ソースツリー中にはインフォファイル(.info)が用意されているので,細かなオプションなどはinfoコマンドで参照できるのですが,その内容は百科辞典的で「実践で役立つ」内容からはほど遠いものです.

 今回の特集では,第2章以後で,オリジナルLinuxブートローダの作成を通じて,GNU開発ツール使いこなしのノウハウを解説します.具体的なコーディングの実例を用いながら,リアルモードでのプログラミング方法,リンカスクリプトの記述方法などについて詳細に解説します.

〔図2〕GNU開発ツール

● 混迷するLinux起動シーケンス

 Linuxカーネルを再構築すると,bzImageという圧縮型のイメージファイルがarch/i386/boot/ディレクトリに生成されます.このファイルをフロッピーディスクにddコマンドでベタ書きすると,Linuxブートフロッピーとして利用できるため,緊急時などにはたいへん便利です.

 ところが,Linuxをターゲットシステムに移植するとなると,これらの便利さが逆にあだとなってしまいます.カーネルソースツリーの解読を始めると痛感させられますが,Linuxの起動部分は超スパゲッティ状態であり,5分も読み進めると気分が滅入ってしまうほどの代物です.可読性も何もあったものではありません.さらに悪いことには,ここにブートローダLILOが加わってくるので,Linux起動コードの読破は並大抵の努力で実現できるものではありません.かりに読破できたとしても,果たして得られるものがあるのかどうか…….

 そこで筆者は,コードの追跡はいさぎよく諦め,みずからブートローダを書き下ろすことにしました.この作業のために,ソース中から必要最小限のエッセンス部分だけを抽出し,最終的にブラックボックスがいっさい存在しないブート環境を作り上げました.第2章と第3章では,BIOS版「Hello,world!」に始まり,順を追いながらコードに機能の追加を行い,最終的なブートローダまで進化させていきます.本特集を読み終わる頃には,Linuxブート機構の全体像を明瞭に俯瞰できることでしょう.

 なお,ブートローダの動作をチェックするために,フリーのx86 CPUエミュレータであるBochsを採用しました.BochsはVMwareとは異なり,x86 CPUを完全にソフトウェア上でエミュレーションします.このため,動作速度が遅いという欠点はありますが,数多くのプラットホーム上で作動し,マルチCPUまでサポートする優れものです.しかも,デバッガ機能が組み込まれているので,各ステップでのレジスタ内容はもちろん,メモリ内容,仮想メモリ・ページテーブルなど,CPU内部およびメモリ状況を事細かく把握することが可能になっています.BochsについてはAppendixで紹介します.

 マイクロプロセッサはコンピュータ会社が独占していたコンピューティングパワーを創造に挑戦する若い開発者に解放し,パソコン,ワークステーション,ゲーム機を登場させ,ソフトウェア産業を大きく花開かせました.

 現在,第2次大戦後に日本が強力に押し進め,高度成長をもたらした高度技術・大量生産という文明の創造と発展にかげりが出始めています.その一方で,アメリカはパソコンという文明の上に,OS,アプリケーション,マルチメディアなどの文化を創造し発展させてきました.

 日本が今のまま生産という文明を重要視しすぎると,日本が莫大な資金を投入して苦労して築き上げた文明の上に,米国の文化を構築するような体制になってしまい,大きな付加価値を日本が享受できなくなってしまいます.また,アメリカで開発された技術を重要視しすぎると,翻訳されたアメリカの文化が日本に浸透し,アメリカ流の表現方法,思考方法,仕事の進め方,価値観が主流となり,会社や社会のあり方までが変化し,日本本来の文化が消滅してしまう恐れがあります.

 現在,学生や技術者が養成すべき能力は,問題を見つけ,本質を見抜き,創造するための,考え出す能力(知恵)であると考えています.

インデックス
序章
 1.PC-UNIXの普及と従来型パッケージの限界
 2.Linuxの理解をはばむもの
 3.本質を見極めよう
Chapter1
 1.プログラムの再考
 2.共有ライブラリの正体

今月号特集トップページへ戻る


Copyright 2002 西田 亙