オペレーティングシステムは、その基礎であるハードウェアシステムと密接に協調 しながら動作しなければならない。そして、オペレーティングシステムはハードウェア でしか提供できない一定のサービスを必要としている。 オペレーティングシステムを完全に理解するには、その基礎となるハードウェアの基本 を理解しなければならない。この章では、そうしたハードウェア、すなわち現代の PC について簡単に紹介する。
1975 年 1 月、「Popular Electrics」誌がその表紙に Altair 8080 のイラストを 載せたとき、革命が始まった。Altair 8080 は、初期のスタートレックのエピソード の目的地にちなんで名付けられていたのだが、家庭電子工作の愛好家がわずか 397 ド ルで組み立てられるというものだった。Intel 8080 プロセッサと 256 バイトのメ モリ、スクリーンもキーボードもないというそのマシンは、今日の基準からすれば 随分貧弱ではある。その発明者 Ed Roberts は、かれの発明品を呼ぶために 「パーソナルコンピュータ(PC)」という言葉を作り出した。しかし今日ではこの PC という言葉は、目の前にあるほとんどあらゆるコンピュータに対して当たり前のよう に使われていている。この定義からすると、非常にパワフルな Alpha AXP のシステム のいくつかでさえ PC ということになる。
熱心なハッカーたちは、Altair の潜在能力を理解し、そのためのソフトウェアを書き、 ハードウェアを作り始めた。そうした初期のパイオニアたちにとって、それは自由の 象徴であった。その自由とは、エリート聖職者階級によって守られて稼働してい た、巨大なバッチプロセス方式のメインフレームシステムからの自由であった。 一夜にして富豪となる「落ちこぼれ」大学生たちが現れたのも、こうした現象、 すなわち自宅のキッチンテーブルに置くことができるコンピュータという産物に 魅了されてのことだった。多くのハードウェアが 出現し、それらは少しずつ違っていたから、ソフトウェアハッカーたちはそうしたマ シンのソフトを喜んで書いていた。逆説的なのは、現代の PC の強固な鋳型を作った のは、IBM であったことだ。彼らは 1981 年に IBM PC を告示して、1982 年はじめに は顧客に出荷し始めた。Intel 8088 プロセッサ、64k のメモリ(256k まで拡張 可能)、ふたつのフロッピーディスク、25 行 80 文字のカラーグラフィックアダプタ (CGA)というスペックは、今日の基準からすると決してパワフルとは言えないが、売れ 行きは好調であった。1983 年には IBM PC-XT が登場し、それには贅沢にも 10M バイ トのハードドライブが付いていた。 まもなく、Compaq などの多くの会社によって IBM PC クローン が製造されはじめ、PC アーキテクチャは事実上の標準となった。この事実上の標準 が出来たことで、成長する市場で無数の会社が競争し、消費者にとっては幸運なこと に、価格は低く抑えられた。こうした初期 PC のシステムの構造上の多くの特徴が、 現代の PC にも受け継がれている。たとえば、最も強力な Intel Pentium Pro ベースの マシンでも、起動時は Intel 8086 のアドレッシングモードで実行されている。 Linus Torvalds が将来 Linux となるはずのコードを書き始めたとき、最も普及して いて妥当な値段のハードウェアとして彼が選んだのが、Intel 80386 PC であった。
(図表1.1) 典型的な PC マザーボード
外観からすると、PC を構成する部品として最も目立つのは、システムの本体であ り、キーボード、マウス、モニターである。本体の前面には、いくつかのボタン、 数字を表示する小さなランプ、それにフロッピードライブがある。最近のシステム では CD-ROM があり、データ保護の必要を感じているならバックアップ用のテープ ドライブもあるだろう。それらのデバイスの総称は、周辺機器である。
CPU がシステム全体をコントロールしているのだが、情報処理機能を持つデバイスは それだけではない。たとえば、IDE コントローラのような周辺機器のコントローラは すべてあるレベルの情報処理能力を持っている。PC の内部には(図表(1.1)参照) マザーボードがあり、 CPU もしくはマイクロプロセッサ、メモリ、ISA や PCI の周辺機器コントローラ 用のいくつかのスロットなどがある。IDE ディスクコントローラのようなコントローラ の中には、システムボードに直接組み込まれているものもある。
CPU もしくはマイクロプロセッサは、あらゆるコンピュータシステムの心臓部であ る。マイクロプロセッサは、計算し、論理演算を行い、メモリから命令を読み出して それらを実行することでデータフローを管理する。コンピュータの黎明期には、 マイクロプロセッサの演算処理部分は独立した(しかもかなり大きな)ユニットであっ た。中央演算処理装置(CPU)という言葉が作られた当時はそういうものであった。 現代のマイクロプロセッサは、それらすべての部品を組み合わせて集積回路を作り、 非常に小さなシリコンチップにエッチング処理されている。CPU, マイクロプロセッ サ、プロセッサといった用語は、本書ではすべて同じ意味で使用される。
マイクロプロセッサは、バイナリデータを処理する。バイナリデータとは、1 と 0 から成るデータである。 これらの 1 と 0 とは、電子スイッチのオンかオフかに対応している。単に 42 と いうと、十進数で " 10 が 4 つと 2 " を意味するが、バイナリナンバー(二進数) では、一連の二進数値の並びとなり、それぞれが 2 のベキ数を表す。
ここでベキ数とは、ある数を自乗する回数のことである。10 の 1乗
(
しかし、コンピュータプログラムの中で数を表現する場合には、二進数よりもむし ろ、もう一つの基数である、十六進数のほうを使用するのが通常である。
16 進数では、それぞれの数が 16 のベキ数になっている。10 進数では 0 から 9 までしかないが、16 進数では 10 から 16 までが A, B, C, D, E, F という数で表現 される。たとえば、16 進数の E は、10 進数では 14 であり、16 進数 2A は、10 進数 では 42 ( 16x2 + 10 ) である。C プログラム言語の表記法では(本書ではこの表記法 に従う)、16 進法は、先頭に " 0x " を付ける。したがって、16 進数 2A は、0x2A と 表記される。
マイクロプロセッサは、加算、乗算、除算などの算術演算や、「X は Y より大きい か?」といった論理演算ができる。
プロセッサの処理は、外部クロックで管理されている。このクロックは、システム クロックであり、プロセッサに一定間隔でクロックパルスを送り、そのクロックパル スごとにプロセッサが何らかの処理をする。たとえば、プロセッサはクロックパルス ごとに命令を実行したりする。プロセッサの速度は、システムクロックの発振速度で 記述される。100MHz のプロセッサは、一秒間に 100,000,000 回のクロックパルスを 受けているわけである。 確かに、プロセッサが違えばクロックごとに実行している処理の量も違うので、CPU の パワーをクロック速度で考えるのは誤解である。しかし、他のすべての条件が 同じであれば、クロック速度が速いほどプロセッサもパワフルなものになる。 プロセッサで処理される命令は単純である。たとえば、「メモリ上の X という場所に ある内容を読んでレジスタ Y に書き込め」といったものである。レジスタとは、 マイクロプロセッサ内部の記憶装置で、データを蓄え、そのデータを使って処理を 実行するために利用される。 実行される処理によっては、実行中の処理を停止して、メモリのどこか違う場所 に存在する別の命令処理に移るようプロセッサに命ずるものもある。このように処理 の対象を小さく分割したことによって、現代のマイクロプロセッサは、毎秒数百万や 数十億という命令の処理ができる、無限ともいえる力を手に入れたのである。
命令は、実行時にメモリから取り出されなければならない。命令はそれ自体が メモリ内の参照データであり、それらのデータはメモリから取り出されなければなら ず、適切な時にメモリに保存されなければならない。
マイクロプロセッサ内のレジスタのサイズ、数、タイプは、完全にプロセッサのタ イプに依存している。Intel 4086 (訳注:80486か?)プロセッサは、Alpha AXP プロ セッサとは違ったレジスタのセットを持っている。たとえば、Intel のものは 32 ビッ ト幅だが、Alpha は、64 ビット幅であることからすでに異なっている。しかし、一般 的には、どのようなプロセッサでも、多くの汎用レジスタと、それよりも少ない数の 特別なレジスタを持っている。大部分のプロセッサには、次のような特定の目的に特 化したレジスタがある。
このレジスタは、次に実行される命令のアドレスを保持するものである。このカウンタ (PC) の内容は、命令がメモリから転送されるたびに、自動的にインクリメントされ る。
プロセッサは、メモリ(Random Access Memory, RAM)にアクセスできなければならな い。メモリは、(レジスタと比較した場合)大容量の、CPU 外部にある読み書き可能な 記憶装置であり、一時(temporary)データの保存を容易にするものである。スタックは、 外部メモリに一時的に値を保存したり取り出したりするための簡単な方法である。 通常、プロセッサは、特別な命令を使って、スタックに値を積み(push)、あとでそれ を取り出す(pop)処理をする。スタックは、後入れ先出し(Last In First Out, LIFO) の原則で動く。言い換えると、x と y のふたつの値を順にスタックに積んでそこから ひとつの値を取り出すと、値 y が取り出される。
あるプロセッサでは、スタックはメモリの上限に向かって積み上げられ、他の プロセッサでは、メモリの下限あるいは最初に向かって積み上げられる。あるいは、 ARM のように両方をサポートしているプロセッサもある。
命令が実行されると結果が生じる。たとえば、「レジスタ X の内容は、レジスタ Y の 内容より大きいか比較せよ」という命令には、大小という真か偽かの結果が生じる。 PS レジスタは、こうした結果を保持するとともに、プロセッサの現在の状態について の情報も保持する。たとえば、大部分のプロセッサは、カーネルモード(あるいは、 スーパバイザーモード)とユーザモードという少なくともふたつのモードを持っている。 PS レジスタは、現在のモードを識別する情報も保持する。
すべてのシステムには、記憶階層(memory hierarchy)がある。そしてその階層の 位置によって、メモリのスピードやサイズが異なる。最速のメモリはキャッシュ メモリ(cache memory)と呼ばれ、その名前の通りメインメモリの内容を一時的に保持 あるいはキャッシュするために使用される。この種のメモリは非常に高速だが高価 なので、大部分のプロセッサではチップ上に少量しか組み込まれず、マザーボード 上にそれより少し多いキャッシュが置かれるだけである。 プロセッサによっては、命令とデータの両方をひとつのキャッシュに保持するものが あるが、命令とデータを別々のキャッシュに保存するものもある。Alpha AXP プロセッサはふたつの内部キャッシュを持ち、ひとつはデータ用(D-Cache)、もうひと つは命令用(I-Cache)として使用される。そして、外部キャッシュ(B-Cache)は、両者 を同時に保持する。最後にメインメモリがある。これは外部キャッシュに比べると 非常に速度が遅い。CPU 上のキャッシュと比較すると、メインメモリはイモ虫ほどの 速度でしかない。
キャッシュとメインメモリとは足並みが揃っていなければならない(一貫性, coherent)。言い換えると、メインメモリ上のあるワード(word)がひとつ以上の キャッシュに保持されている場合、(システムは)キャッシュとメモリの内容を確実に 一致させなければならない。キャッシュの一貫性を保つのは、主にハードウェ アの仕事であり、オペレーティングシステムも部分的にそれに関与する。このことは 多くの重要なシステムタスクにも当てはまる。ハードウェアとソフトウェアが緊密に 協調することで目的を達成しなければならないタスクは数多くある。
システムボード上の個別の部品は、バスと総称される多様な接続方法で互いに結び つけられている。システムバスは、論理的な機能から次の 3 つに分類される。 アドレスバス、データバス、そしてコントロールバスである。アドレスバスは、データ 転送のためにメモリ上の位置(アドレス)を指定するものであり、データバスはデータ を保持して転送するするためのものである。データバスは双方向性で、CPU に読み 込まれるデータと、CPU から書き込まれるデータの転送を受け持つ。コントロールバス は多種の信号線を含んでいて、クロックパルスや制御シグナルなどを(バス上の)シス テム全体に配線するために使用される。それら以外にも様々な形態のバスが存在する。 たとえば ISA や PCI バスは、システムに周辺機器を接続する際の一般的な方法であ る。
周辺機器は、グラフィックカードやディスクといった実(real)デバイスであり、 それらは、システムボード上のチップやボードに差されるカード上のコントローラに よって制御される。IDE ディスクは、IDE コントローラチップで制御され、SCSI ディスクは SCSI ディスクのコントローラチップで制御される。それらのコントローラ は CPU に接続されていて、多様なバスにより相互にも接続されている。今日製造される 大部分のシステムでは、PCI か ISA バスによってメインシステムの部品に相互接続 されている。コントローラは、CPU 自体と同じプロセッサーであり、CPU を助ける 情報処理装置と考えることもできる。CPU はシステム全体を統括している点でそれらと 役割が異なる。
コントローラの仕様は相互に異なっているが、通常はレジスタを持ち、それによって コントローラの制御がなされる。CPU 上で実行されるソフトウェアは、そうしたコン トローラの制御レジスタを読み書きできなければならない。あるレジスタはエラーを 示すステータス情報を保持しているかもしれず、他のレジスタは、コントローラの モード変更のための制御目的で使用されているかもしれない。バス上にある個々の コントローラは、CPU で個別にアドレス管理されているので、それによって、 ソフトウェアであるデバイスドライバは、コントローラのレジスタに書き込みをし て、それらを制御することができる。IDE ポート(IDE ribbon)がその典型であり、 それを使用することで、バス上のデバイスに対する個別のアクセスが可能になる。 他の典型例は、PCI バスであり、これによっても個別のデバイス(たとえば、グラフィッ クカード)に独立してアクセスが可能となっている。
システムバスは、CPU をメインメモリに接続するものであり、CPU をシステムの 周辺機器に接続するバスとは区別されている。周辺機器が占めるメモリ空間は、 I/O 空間(I/O space)と総称される。I/O 空間はそれ自体さらに細かく分かれるのだ が、現時点ではあまり気にしないこととする。CPU はシステム空間メモリと I/O 空間 メモリの両方にアクセス可能なのだが、コントローラ自体はシステムメモリに間接的 にアクセスできるだけであり、その際には CPU の助けを借りなければならない。 フロッピーディスクコントローラのようなデバイスの側からこれを見ると、デバイス はデバイスのコントロールレジスタが占めるアドレス空間しか見ることはできず (ISA 等の場合)、システムメモリを見ることはできない。 CPU は、システムメモリにアクセスする場合と I/O 空間にアクセスする場合とでは 別々の命令を持っているのが一般的である。たとえば、「I/O 空間のアドレス 0x3f0 から 1 バイト読み出して、レジスタ X に入れよ」という命令があったとする。 これは CPU がシステムの周辺機器を制御する方法そのものであり、I/O 空間にある 周辺機器コントローラのレジスタの読み書きがまさにそれにあたる。 PC アーキテクチャが今日のように発展しても、I/O 空間のどこに、よく利用される 周辺機器( IDE や シリアルポートやフロッピーのコントローラ)のレジスタがあるか は、長年の慣習によって決まっている。上記の I/O 空間のアドレス 0x3f0 は、 シリアルポート(COM1)のコントロールレジスタのひとつがあるアドレスとなっている。
時には、コントローラが、システムメモリに対して直接大量のデータを読み 書きする必要が生じる場合がある。たとえば、ユーザデータがハードディスクに書き込 まれるような時である。その場合、DMA(Direct Memory Aceesss)コントローラが利用さ れ、周辺機器が直接システムメモリにアクセスできるようになっている。DMA による システムメモリへのアクセスは、CPU の厳しい管理・監督のもとで行われる。
時間を知ることはすべてのオペレーティングシステムにとって必要なことなので、 現代の PC にはリアルタイムクロック(Real Time Clock, RTC) と呼ばれる特別の 周辺機器が組み込まれている。これが提供するのは、その日の正確な時間と精密な タイミングインターバル(timing interval)のふたつである。RTC には内蔵バッテリー があるので、PC に電源が入っていない時でも実行し続けることができる。それゆえ PC はいつも正確な日付と時間とを知っているわけである。インターバルタイマーに よって、オペレーティングシステムは重要な処理を正確にスケジューリングすること が可能となる。