  The Unix and Internet Fundamentals HOWTO
  by Eric S. Raymond
  v1.1, 3 December 1998
  堀田 倫英（翻訳）sim@remus.dti.ne.jp
  15 January 1999

  この文書では、PC クラスのコンピュータや Unix ライクなオペレーティン
  グ・システム、およびインターネットについての基礎的な事柄について、なる
  べく技術的な用語を使わないようにしながら説明します。
  ______________________________________________________________________

  Table of Contents

  1. はじめに
     1.1 この文書の目的
     1.2 関連する文書
     1.3 New versions of this document
     1.4 この文書の新しいバージョン
     1.5 フィードバックと修正

  2. あなたのコンピュータを解剖してみましょう
  3. コンピュータの電源を入れたら何が起こるの？
  4. シェルからプログラムを起動したら何が起こるの？
  5. 入力装置と割り込みってどうやって動くの？
  6. コンピュータはどうやって複数のことを同時に行うことができるの？
  7. コンピュータはどうやって複数のプロセスをお互いに干渉し合わ ないようにしているの？
  8. コンピュータはどのようにしてディスク上に情報を格納するの？
     8.1 低レベルのディスクとファイルシステム構造
     8.2 ファイル名とディレクトリ
     8.3 マウントポイント
     8.4 どうやってファイルを検索するの？
     8.5 どうして動作がおかしくなるのでしょう？

  9. コンピュータ言語っていうのはどうやって動くの？
     9.1 コンパイル言語
     9.2 インタプリタ言語
     9.3 P コード言語

  10. インターネットはどうやって動いているの？
     10.1 名前とその位置
     10.2 パケットとルータ
     10.3 TCP と IP
     10.4 HTTP、あるアプリケーションプロトコル

  11. 和訳版の校正
     11.1 翻訳の校正
     11.2 SGMLのチェック

  ______________________________________________________________________

  1.  はじめに

  1.1.  この文書の目的

  この文書は、試行錯誤しながら学んでいる Linux とインターネットユーザの
  ために書かれました。そのようにして学んでいくことは実りの多い方法なんで
  すが、時には現在持っている基礎知識との独特なギャップを感じることがある
  でしょう。そのギャップが、いま実際に何が行われているのかということを頭
  の中に描けなくしてしまい、創造的に考える事や、効率的にトラブルを解決す
  る事を難しくしたりしてしまうのです。

  ここでは、すべてのことがどうやって動いているのかということが明らかにな
  るように、明解かつ平易な言葉で述べてみようと思います。この文書の発表に
  よって、ＰＣクラスのハードウェアで Unix や Linux を使っている方々を落
  ち着かせることができるでしょう。やはりここでは単に 'Unix' について語る
  ことにします。私が言おうとしていることは、各プラットフォームや 'Unix'
  のさまざまな変種に関して共通のことだからです。

  ここでは、あなたが Intel ベースの PC をお使いになっていると仮定しま
  す。もしあなたが Alpha や PowerPC、もしくはそれ以外の Unix Box をお使
  いの場合でも違いは微々たるもので、基本的な設計思想は同じです。

  いろいろなことを繰り返し述べたりはしませんので注意してください。つま
  り、ここに書いてある１語１語から意味を読み取って欲しいということです。
  最初はこの文書をざっと斜め読みするのも悪くはありませんが、学んだ事が少
  しまとまってきたら、また何度か繰り返して読んでみる事をお勧めします。

  この文書は随時発展していきます。私はユーザーのフィードバックに応じて記
  述を追加していくつもりですので、定期的に読むことをお勧めします。

  1.2.  関連する文書

  ハックするやり方を学ぶためにこの文書を読む場合は、 How To Become A
  Hacker FAQ <http://www.tuxedo.org/~esr/faqs/hacker-howto.html>も読んで
  おいた方がよいでしょう。ここはその他の有用な文書にリンクしています。

  1.3.  New versions of this document

  1.4.  この文書の新しいバージョン

  the Unix and Internet Fundamentals HOWTO の新しいバージョンは、定期的
  に comp.os.linux.help、および news.answers <news:answers> に投稿されま
  す。またそれらはもちろん LDP ホームページなどあちこちの Linux の WWW
  や ftp サイトにアップロードされます。

  この文書の最新バージョンは、
  <http://sunsite.unc.edu/LDP/HOWTO/Fundamentals-HOWTO.html>.  におい
  て、World Wide Web 経由でご覧いただけます。

  1.5.  フィードバックと修正

  この文書に対して質問やコメントがある場合は、ご遠慮なく esr@thyrsus.com
  の Eric S.Raymond <esr@thyrsus.com> までメールしてください。いかなる提
  案や批判も歓迎します。特に、個々のコンセプトに関するより詳細な説明への
  ハイパーリンクがあればなお結構です。この文書に誤りを見つけた場合は、私
  にお知らせいただければ次のバージョンで修正します。どうぞご協力を。

  2.  あなたのコンピュータを解剖してみましょう

  コンピュータの中には、実際の処理を行うプロセッサ・チップが入っていま
  す。また、内部メモリも持っています。メモリのことを DOS/Windows な人た
  ちは 'RAM' と呼びますが、Unix な人たちはよく 'core（コア）' と呼びま
  す。プロセッサとメモリは、あなたのコンピュータの心臓部であるマザーボー
  ド 上で動きます。

  コンピュータには画面とキーボードがついています。またハードディスクやフ
  ロッピーディスクもあります。画面やディスクには、マザーボードに組み込む
  ための コントローラ・カード がついており、これによってコンピュータがそ
  れらの出力デバイスの駆動を行うことができるようになっています。（キーボ
  ードは非常にシンプルな作りをしているので、それ専用のカードは不要です。
  コントローラはキーボードの筐体自体に組み込まれています。）

  後の方では、これらのデバイスがどうやって動くのかといった詳細に踏み込ん
  で行きます。現時点では、それらがどうやって協調して動くのかということに
  関する、ぜひとも覚えていただきたい基礎的な事柄を解説していきます。

  コンピュータの中にあるすべての内部パーツはバスで接続されています。物理
  的には、バスは（ビデオ・カード、ディスク・コントローラやサウンド・カー
  ドなど、あなたがお持ちの）コントローラ・カードを差し込むものであり、あ
  なたのプロセッサ、画面、ディスクその他すべての間にあるデータの高速道路
  です。

  プロセッサは、その他すべてのものを動作させるためにあるのですが、実際に
  は他のパーツを直接見ることができず、バスを通じて会話することしかできま
  せん。プロセッサが持つ、非常に高速でしかも直にアクセスできる唯一のもの
  はメモリ（コア）です。このため、プログラムを動作させるためには、プログ
  ラムはコアの中にある必要があります。

  コンピュータがプログラムやデータをディスクから読み出す際に実際に行って
  いることは、プロセッサがバスを使ってディスクのリード要求をディスク・コ
  ントローラに送ることです。しばらくしてからディスク・コントローラはバス
  を使ってコンピュータにシグナル（信号）を送ることで、データを読み込んで
  コアの中の特定の位置に置いたことを知らせます。その後プロセッサはバスを
  使ってそのメモリを見に行きます。

  キーボードと画面もまたバスを経由してプロセッサと通信を行いますが、これ
  はより単純な方法で行われます。これについては後述します。現時点では、コ
  ンピュータの電源を入れたときに何が起こるのかをあなたが理解するのにはこ
  れで十分です。

  3.  コンピュータの電源を入れたら何が起こるの？

  プログラムが動いていないコンピュータは、言わば電気で動く鉄のかたまりで
  す。電源が投入された時にコンピュータがまずやらなければならないことは、
  オペレーティング・システムと呼ばれる特殊なプログラムを開始させることで
  す。オペレーティング・システムの仕事は、コンピュータのハードウェアを制
  御するというやっかいな処理を行なうことにより、他のコンピュータ・プログ
  ラムが動作する手助けをしてやることです。

  オペレーティング・システムを起動する処理のことをブートといいます（これ
  は元々 ブートストラッピング (bootstrapping)といい、「自力で（'by your
  bootstraps'）」有効な稼動状態になることが困難なことから来ています）。
  コンピュータがブートの方法を知っている理由は、ブートのための命令がその
  チップのうちの１つ、BIOS（またはBasic Input/Output System＝基本入出力
  システム）チップに埋め込まれているからです。

  BIOS チップは、最小の番号がついているハードディスク（ブートディスク）
  上の決まった位置にある、ブートローダと呼ばれる特殊なプログラムを探しま
  す（Linux ではブートローダは LILO と呼ばれています）。ブートローダはコ
  アに読み込まれ、動作を開始します。本当のオペレーティング・システムを開
  始させることがブートローダの仕事です。

  ローダはこの処理を行うために、カーネルを検索してそれをコアにローディン
  グ（読み込み）し、そしてカーネルを始動させます。Linux をブートすると画
  面に "LILO" という文字が現れ、続けてドットが１つずつ表示されていきます
  が、まさにこの時カーネルをローディングしているのです（表示される各ドッ
  トは、読み込んだカーネルコードの ディスク・ブロックを表しています）。

  （なぜ BIOS がカーネルを直接ロードしないのか、不思議に思われる方もい
  らっしゃるかもしれません。なぜブートローダで２つの過程を踏むのでしょ
  う？これはですね、BIOS っていうのはあまり賢くないからです。実際こいつ
  はとても頭が悪いので、ブートが完了した後 Linux は全く BIOS を使いませ
  ん。これは元々ディスクもあまり積んでいない原始的な 8 ビットＰＣのため
  に書かれたもので、カーネルを直接ロードするようなディスクアクセスは事実
  上できないのです。ブートローダの過程においても、ディスク上の異なった場
  所からいくつかのオペレーティング・システムを開始させることはできます
  が、これは Unix の機能では不可能なことなのです。）

  いったんカーネルが動作を開始すると、カーネルは周辺装置を検索してその他
  のハードウェアを見つけ、そしてプログラムが動作するための準備を完了しま
  す。この処理は、通常のメモリ位置ではなく I/O ポート −−− デバイスの
  コントローラ・カードがコマンドを受け付けるために監視していると思われ
  る、特別なバスのアドレス −−−にある値を書き込むことによって行われま
  す。カーネルはランダムに値を書き込むわけではありません。カーネルには、
  どこのポートに書き込みに行けばよいか、またそこにコントローラが存在した
  場合どのように反応するべきかについて、あらかじめ組み込まれた情報を持っ
  ているのです。この処理のことをハードウェアの自動認識(autoprobing)とい
  います。

  ブート時に表示されるメッセージのほとんどは、カーネルによるハードウェア
  の自動認識機構が I/O ポートを通してハードウェアにアクセスし、それが使
  用可能であればそれらをマシンに組み込んでいる様子を示しています。Linux
  のカーネルはこの機能については良くできていて、他のほとんどの Unix に優
  り、ましてや DOS や Windows よりは はるかに 優れています。実際、昔から
  の Linux 使いの方々は、Linux のブート時におけるハードウェアの自動認識
  機能の賢さ（インストールの簡単さに通じる）が、Linux が Free-Unix の一
  連の実験段階から抜け出し、口うるさい大衆ユーザーを魅了するようになって
  きた主な要因だったと考えています。

  しかしながら、カーネルのロードが完了して動作を開始することで、ブート処
  理が終わったわけではありません。まだほんの初期の段階です（ランレベル１
  と呼ばれることもあります）。

  カーネルの次のステップでは、ディスクが正常であるかどうかを確認します。
  ディスクのファイルシステムとは壊れやすいものです。もしそれらがハード
  ウェアの故障や突然の電源遮断などによってダメージを受けていれば、Unix
  がすべての面で完全に立ち上がる前にファイルシステムの修復を行う必要があ
  ります。後述の ``ファイ ルシステムはどうやって壊れるのか'' で、このこ
  とについて触れます。

  カーネルの次のステップでは、いくつかの デーモン を開始させます。デーモ
  ンとは、やるべきことを待ちながらバックグラウンドでこっそり動く、プリン
  トスプーラやメールサーバ、WWW サーバといったプログラムのことです。これ
  らの特別なプログラムは、競合する複数の要求を調整しなければならないこと
  が往々にしてあります。これらをデーモンとする理由は、多数のプログラムの
  コピー（各々が１つの要求を処理して、それらがすべて同時に動いている）
  に、お互いに他の処理に影響を及ぼさないかを確認させようとするよりは、
  ずっと動きっぱなしで、すべての要求について知っている１本のプログラムを
  書く方が簡単だからです。あなたのシステムで開始されるこの特殊なデーモン
  群はシステムにより異なっているかもしれませんが、ほとんどの場合その中に
  はプリント・スプーラ（プリンタの番人）が含まれます。

  いったんすべてのデーモンが開始されると、ランレベル２ に入ったことにな
  ります。次のステップではユーザーに対する準備を行います。カーネルは
  getty と呼ばれるプログラムのコピーを起動することにより、あなたのコンソ
  ールを監視します（場合によっては、それ以上の数のコピーがダイヤルイン用
  のシリアル・ポートを監視することもあります）。このプログラムは、あなた
  のコンソールに ログイン プロンプトを表示します。ここでランレベル３に到
  達し、ユーザーがログインしてプログラムを動かすための準備が完了したこと
  になります。

  あなたが（ユーザー名とパスワードを入力して）ログインした時、あなた
  はgetty とコンピュータの両方から認識されています。getty はその後 login
  と呼ばれるプログラム（そのまんまですね）を動作させますが、これは若干の
  管理作業を行った後、コマンド・インタプリタ、つまり シェル を起動しま
  す。（そう、gettyとlogin は１つのプログラムであってもいいのです。それ
  らは歴史的な理由から別々のプログラムになっていますが、それはここでご紹
  介するほどの理由ではありません。）

  次の節では、シェルからプログラムを起動したときに何が起こるのかについて
  ご説明します。

  4.  シェルからプログラムを起動したら何が起こるの？

  通常のシェルでは、ログインすると（何か他のものにカスタマイズしていない
  限り） '$' プロンプトを表示します。ここではシェルの文法や、画面に表示
  されるものについては触れません。そのかわり、ここで起こっていることの背
  景について、コンピュータの視点から考察してみます。

  ブートも終わり、あなたがプログラムを起動しようとする前に思い出していた
  だきたいことは、コンピュータの中には何かするべきことを待っているプロセ
  スの一群がいるということです。それらはすべて イベント を待っています。
  イベントとは、あなたがキーを押したとかマウスを動かしたなどの事象です。
  また、あなたのマシンがネットワークに接続されていれば、そのネットワーク
  を通してそのマシンに入ってきたデータパケットもイベントのうちの１つとな
  ります。

  カーネルもまたこれらのプロセスの仲間です。カーネルが特殊なのは、その他
  の ユーザープロセス が動作できるときにはそれらをコントロールし、また通
  常マシンのハードウェアに直接アクセスできるただ１つのプロセスだからで
  す。実際、ユーザープロセスは要求を作成してカーネルに伝えることにより、
  キーボード入力を取得したり、画面に書き込んだり、ディスクの読み書きをし
  たりしなければならず、ただ１つ自分でできることは、メモリの中でビット操
  作や計算をしたりすることくらいです。これらの要求は、システムコールとし
  て知られています。

  通常すべての I/O はカーネルを通して行われるので、カーネルは操作のスケ
  ジューリングを行ったり、各プロセスがお互いに影響を及ぼさないように守っ
  てやることができます。ごく一部の特殊なユーザープロセスでは、I/O ポート
  への直接のアクセス権を持つことにより、カーネルのあずかり知らないところ
  で動作することが許されるものもあります。これの一番典型的な例としては X
  サーバ（ほとんどの Unix Box において、他のプログラムの要求を処理してグ
  ラフィックス画面に描画するプログラム）があります。しかし我々はまだ X
  サーバまではたどりついていません。あなたはまだキャラクタ・コンソール上
  のシェル・プロンプトを見ているだけなのです。

  シェルも単なるユーザープロセスの１つであり、別に特殊なものではありませ
  ん。シェルは（カーネルを通して）キーボードの I/O ポートを監視すること
  によりキーストロークを待ちます。カーネルがキーの押下を検出すると、それ
  らを画面にエコー（表示）すると同時にシェルに渡します。カーネルが
  'Enter' を検出すると、テキスト行をシェルに渡します。そしてシェルはそれ
  らのキーストロークをコマンドとして解釈しようとします。

  たとえば 'ls' とタイプして Enter を押すと、Unix のディレクトリ一覧表示
  機能が起動されます。シェルはその組み込み(built-in)ルールを適用して、あ
  なたが '/bin/ls' ファイルという実行可能コマンドを走らせたいということ
  を理解します。そしてシステムコールを発行して /bin/ls を新しい 子 プロ
  セスとして開始することをカーネルに対して要求し、その子プロセスに対して
  カーネルを通して画面とキーボードに対するアクセス権を与えます。その後
  シェルはスリープし、 ls が終わるのを待ちます。

  /bin/ls は、動作し終わると exit システムコールを発行してその終了をカー
  ネルに通知します。するとカーネルはシェルを起こして(wake-up)動作を続行
  するよう指示します。シェルは次のプロンプトを発行して次の入力行を待ちま
  す。

  しかしながら、'ls' が実行されている間にあなたは別のことを行ってもかま
  いません（たとえばあなたが、とても長いディレクトリのリストを出している
  としましょう）。あなたは他の仮想コンソールに切り替えてそこでログイン
  し、Quake のゲームを始めてもよいのです。または、あなたがインターネット
  とつながっているとしましょう。あなたのマシンは /bin/ls を実行しながら
  メールの送受信を行うこともできます。

  5.  入力装置と割り込みってどうやって動くの？

  キーボードは非常に単純な入力装置です。なぜ単純かというと、小さな単位の
  データを（コンピュータの標準機能により）非常にゆっくりと生成するだけだ
  からです。キーを押したり離したりすると、そのイベント信号がキーボード・
  ケーブルを伝わって、ハードウェア割り込み を起こします。

  そのような割り込みを監視するのはオペレーティング・システムの仕事です。
  各種の割り込みごとに 割り込みハンドラが用意されています。これはオペレ
  ーティング・システムの一部分で、（キーを押した／離したなどを表す値のよ
  うな）関連するデータを処理できるようになるまで保存しておきます。

  キーボードの割り込みハンドラが実際に行うことは、キーの値をコアの底の方
  にあるシステム領域に格納することです。オペレーティング・システムが、現
  在キーボードからの読み込みを行っていると見なされるいずれかのプログラム
  にその制御を渡した時、そのプログラムは格納された値を調べることができる
  ようになります。

  ディスクやネットワーク・カードなど、より複雑な入力装置の場合も、これと
  よく似た方法で動作しています。ディスク・コントローラは、バスを使って
  ディスクへの要求が満たされたことを表わす信号を伝えていることは前にご紹
  介しました。ここで実際には、ディスクは割り込みを発行しているのです。そ
  の後ディスクの割り込みハンドラは、取り込まれたデータをメモリ中にコピー
  し、その後要求を出したプログラムはそのデータを使うことができます。

  どの種類の割り込みにも、関連する 優先度レベルがあります。低優先度の割
  り込み（キーボード・イベントなど）は、高優先度の割り込み（時刻の刻
  み(clock ticks)やディスク・イベントなど）により待たされます。Unix で
  は、すばやく処理しなければならないようなイベントに対して、マシンの応答
  性をスムーズに保つために高い優先度を割り当てるように設計されています。

  OS ブート時のメッセージの中で IRQ 番号に関するものが表示されると思いま
  す。ハードウェアの構成ミスでよく起こるのが、２つの異なったデバイスが、
  事前の了解無く同じ IRQ を使おうとしてしまうことです。

  解決方法はこうです。IRQ は "Interrupt Request" （割り込み要求）の略で
  す。オペレーティング・システムはその開始時に、各ハードウェア・デバイス
  がどの番号の割り込みを使うのかを把握していなければなりません。２つの異
  なったデバイスが同一の IRQ を使おうとしてしまうと、割り込みが間違った
  ハンドラを駆動してしまうことがあります。通常これは少なくともそのデバイ
  スを探しに行き、OS の動作を狂わせたりクラッシュさせたりする要因となり
  ます。

  6.  コンピュータはどうやって複数のことを同時に行うことができるの？

  これは実際にはできません。コンピュータは同時には１つのタスク（または
  プロセス）だけしか実行できません。しかしコンピュータは、タスクを非常に
  高速に切り替えることができるので、鈍重な我々人間には、同時に複数のこと
  が行われているように見えてしまうのです。これは タイム・シェアリング
  （訳注：時分割）と呼ばれています。

  カーネルの仕事のうちの１つにタイム・シェアリングの管理というものがあり
  ます。これは スケジューラ と呼ばれる部分で行われており、その内部に他の
  すべての（非カーネル）プロセスに関する情報を保持しています。カーネル中
  では60分の１秒ごとにタイマ監視がオフになり、クロック割り込みを生成しま
  す。この時どのプロセスが動作していようと、スケジューラはそのプロセスを
  停止して動作を延期(suspend) させ、制御を別のプロセスに移します。

  60分の１秒という時間はそう長いとは感じないかもしれません。しかしマイク
  ロ・プロセッサは今日一日だけでも何万回というマシン命令を実行しており、
  頻繁な割り込みは非常な負荷となります。このため多くのプロセスが動作して
  いる場合、各プロセスは１回のタイムスライス（訳注：ＣＰＵ時間の割り当
  て）ではほんのちょっとしか動作できません。

  実際は、各プログラムは割り当てられたタイムスライスをほとんど使えないこ
  ともあります。I/O デバイスから割り込みが来た場合、カーネルは効率よく現
  在のタスクを停止し、割り込みハンドラを駆動してからまた現在のタスクに戻
  ります。高優先度の割り込みが殺到した場合、制御が奪われて通常の処理は動
  作不能となります。この現象のことを スラッシング と呼びますが、幸運なこ
  とに最近の Unix ではほとんど起きることはありません。

  実際プログラムの動作速度は、取得可能なマシンタイムによってのみ制限され
  ますが、このような制限はめったに発生することではありません（このルール
  の数少ない例外としては、サウンドや３次元グラフィクスの生成などがありま
  す）。よく発生する事象としては、プログラムがディスク・ドライブやネット
  ワーク・コネクションからのデータを待たなければならない場合、実行の遅延
  が起こります。

  日常的に、同時に動作する多くのプロセスをサポートすることのできるオペレ
  ーティング・システムのことを、"マルチタスキング" と呼びます。Unix ファ
  ミリーのオペレーティング・システムは、当初よりマルチタスキングのために
  設計され、Windows や Mac OS などに比べて非常にうまく機能しています。後
  者の場合、マルチタスキングは後から追加された機能で、あまりうまく実装さ
  れているとはいえません。効率的で信頼性のあるマルチタスキングは、Linux
  でネットワーキングや通信、および Web サービスを行うにあたり、優位性を
  持つための重要な要素となっています。

  7.  コンピュータはどうやって複数のプロセスをお互いに干渉し合わ ないよ
  うにしているの？

  カーネルのスケジューラは、複数のプロセスを時間で分割しています。オペレ
  ーティングシステムも同様に、それらを空間において分割します。このため、
  各プロセスはお互いの作業メモリに入ることができません。オペレーティング
  システムが行うこの問題に対する対処方法のことを、メモリ管理 と呼びま
  す。

  あなたの管理下にある各プロセスには、実行すべきコードを格納したり変数を
  保持して結果を書き込むためのコアメモリの領域がそれぞれ必要になります。
  この領域のセットは、読み込みのみの コードセグメント （プロセスの命令を
  保持している）と、書き込み可能なデータセグメント （プロセス内のすべて
  の変数領域を保持している）から構成されます。データセグメントは各プロセ
  ス間で全くユニークですが、２つのプロセスが同一のコードを実行する場合、
  効率的に管理するために、Unix は自動的に単一のコードセグメントを共有す
  るようにそれらを調整します。

  効率が大切なのは、コアメモリが高価だからです。マシン上で動作しているす
  べてのプログラム全体を保持することができない場合もあります。 X サーバ
  のような巨大なプログラムを使っている時などは特にそうです。この問題を解
  決するために、Unix では 仮想メモリ という手法を使います。この手法で
  は、プロセスのためのすべてのコードとデータをコアに持とうとはしません。
  そのかわり比較的小さな ワーキングセット を保持します。プロセスの中のそ
  れ以外の情報は、ハードディスク上の特殊な スワップスペース 領域に残され
  ます。

  プロセスが動作すると、 Unix はどれくらいのワーキングセットが変更される
  かを予測し、プロセス空間のうち必要最小限の部分をコアの中に持ちます。こ
  れを効果的に行うことは複雑でかつ手の込んだことなので、ここでそのすべて
  を説明することはしません −−− しかしこの手法は、コード及びデータの参
  照において、各々の新しいものが、古いものの近くにあるどこかを参照するこ
  とが多く、またそれが連続して起こる傾向があるという事実に基づいていま
  す。

  注意：過去においては "時には"、２つ前の文では "ほとんど常に" ですが、
  コアのサイズは基本的にプログラムのサイズに比較して小さいため、スワッピ
  ングが頻繁に起こりました。メモリは今日ではもはやそう高価な物ではなく、
  ローエンドのマシンでも十分なメモリを積んでいます。コアに 64MB 以上もの
  メモリを積んでいる最近のシングルユーザー・マシンでは、X に加えて一般的
  なジョブの組み合わせを走らせても全くスワッピングは起こりません。

  この幸せな状況においてもなお、メモリ・マネージャ と呼ばれるオペレー
  ティング・システムの一部分は、未だに重要な役目を果たしています。これ
  は、プログラムが変更するのはそれ自身が保有するデータセグメントのみであ
  るをことを保証しています −−− すなわち、プログラム中のコードが間違っ
  て、もしくは悪意を持ってデータを別の物に書き換えることが起こらないよう
  にしているわけです。メモリ・マネージャ はこれを行うために、データ及び
  コード・セグメントのテーブルを保持しています。プロセスがより多くのメモ
  リを要求したり（通常はプログラムの終了時に）メモリを解放したりするたび
  に、このテーブルは更新されます。

  このテーブルは、MMUまたはメモリ管理ユニットと呼ばれる、ハードウェアに
  位置する特別な部分に対してコマンドを渡すために使われます。最近のプロ
  セッサ・チップでは、それ自身に MMU を内蔵しています。MMU はメモリ領域
  を回りから保護するという役目がありますので、領域を超えた参照は拒否さ
  れ、特殊な割り込みが発生するようになっています。

  もし今までに "Segmentation fault", "core dumped" といった Unix メッセ
  ージを見たことがあれば、まさにこれが起こったということです。動作中のプ
  ログラムがそのセグメント外のメモリをアクセスしようとした場合、致命的な
  割り込みが発生します。これはプログラム中にバグがあることを示していま
  す。この際プログラマがその原因を追究できるように、コアダンプ という診
  断情報が出力されます。

  8.  コンピュータはどのようにしてディスク上に情報を格納するの？

  Unix でハードディスクの内容を見ると、名前の付いたディレクトリやファイ
  ルのツリーがあります。通常それ以上のことを知る必要はありませんが、深い
  ところで何が行われているかを知っていると、ディスク・クラッシュが起こっ
  てファイルを救おうとする場合などに役立つこともあります。残念なことに、
  ディスクの構造をファイルレベルから下の方に下りながら説明するのによい方
  法がないのです。ということで、ここではハードウェアから上の方に向かって
  説明しなければなりません。

  8.1.  低レベルのディスクとファイルシステム構造

  データを格納する場所であるディスクの表面領域は、環状のトラックが前もっ
  てセクタ（sector:扇形）に切り分けられ、ちょうどダート盤のように分割さ
  れています。外側の端に近いトラックは、ディスクの中心部にあるスピンドル
  （中心軸）に近いところより多くの領域を持つため、外側のトラックは内側の
  トラックより多くのセクタに区切られています。各セクタ（またはディスクブ
  ロック）は同一のサイズであり、最近の Unix では一般的に１キロバイト
  （1024 個の 8 ビット・ワード）です。各ディスクブロックはユニークなアド
  レスまたはディスクブロック番号を持っています。

  Unix ではディスクをディスク・パーティションに分けます。各パーティショ
  ンはブロックが連続したもので、ファイルシステムとしてもスワップスペース
  としても、他のどのパーティションとも区別して使われます。一番小さい番号
  がつけられたパーティションは、ブートするカーネルを置くためのブート・パ
  ーティション専用として取り扱われることがしばしばあります。

  各パーティションは、スワップスペース（``仮想メモリ''を実装するために使
  われます）かまたは、ファイルを保持するために使われるファイルシステムの
  いずれかです。スワップスペース・パーティションは単に連続したブロックの
  並びとして扱われます。一方ファイルシステムは、ファイル名をディスクブ
  ロックの並びに対してマッピングするための方法を必要とします。なぜなら
  ば、ファイルというものは時間の経過につれそのサイズが大きくなったり小さ
  くなったり、また内容が変更されたりするので、各ファイルのデータブロック
  は連続した並びではなくなってゆき、そのパーティションじゅうに散り散りば
  らばらになってしまうかもしれないからです（オペレーティング・システム
  は、必要なときにそのパーティションのどこからかフリーブロックを見つける
  ことができるようになっています）。

  8.2.  ファイル名とディレクトリ

  各ファイルシステムにおいては、名前からブロックへのマッピングはｉ-ノー
  ドと呼ばれる構造体を通して行われます。各ファイルシステムの "底" （最小
  の番号がつけられたブロック）の近くに、これらのものをプールしておく場所
  があります（この最小の番号がついた場所は管理やラベリングの目的で使われ
  ますが、ここではふれません）。各々のｉ-ノードは１つのファイルを表しま
  す。ファイルのデータブロックは、ｉ-ノードがあるから成り立っているので
  す。

  各々のｉ-ノードには、それが表すファイルのディスクブロック番号のリスト
  が入っています。（実際は、これは正確ではありません。本当は小さなファイ
  ルについてはのみ当てはまりますが、これに関する具体的な話はここでは重要
  ではありません。）iノードにはファイルの名前が入っているのではないこと
  に注意してください。

  ファイルの名前はディレクトリ構造体の中にあります。ディレクトリ構造体
  は、単に名前からｉ-ノードへのマッピングを行っているだけです。なぜなら
  Unix では、１つのファイルは複数の本当の名前（またはハードリンク）を持
  つことができるからです。それらは単に、たまたま同じｉ-ノードを指してい
  る、複数のディレクトリ・エントリなのです。

  8.3.  マウントポイント

  もっとも単純なケースでは、Unix ファイルシステム全体がただ１つのディス
  ク・パーティション内にあります。ある種の小さなパーソナル Unix システム
  でこのような構成になっていることがありますが、これは例外なのです。より
  一般的には、ファイルシステムはいくつかのディスク・パーティションにまた
  がり、時には異なった物理ディスクにまたがっていることもあります。そこ
  で、たとえばあなたのシステムでは、小さな１つのパーティションにカーネル
  があり、それより少し大きなパーティションに OS のユーティリティが入って
  いて、さらに大きなパーティションにユーザーのホーム・ディレクトリがある
  としましょう。

  システムのブート後すぐにアクセスする唯一のパーティションは ルート・パ
  ーティション です。（ほとんど常に）ここからブートが始まります。ここは
  ファイルシステムのルート・ディレクトリを保持していて、ぶらさがっている
  すべてのものの最上位ノードです。

  システム内のそれ以外のパーティションは、複数パーティションにまたがるあ
  なたのファイルシステム全体がアクセス可能になるように、この根元に接続さ
  れなければなりません。ブート処理の途中頃に、あなたの Unix はこれらルー
  トでないパーティションをアクセス可能にします。これは、そのパーティショ
  ンをルート・パーティション上のあるディレクトリにマウントすることにより
  行います。

  たとえば '/usr' と呼ばれる Unix のディレクトリがありますが、これはおそ
  らくパーティションへのマウントポイントであり、その中には Unix にインス
  トールされている多くのプログラムが入っています。しかしこれらは、初期ブ
  ート時には必要とされないものです。

  8.4.  どうやってファイルを検索するの？

  さて、どうやってファイルをトップダウンで検索すればいいのでしょう。あな
  たがファイル（たとえば /home/esr/WWW/ldp/fundamentals.sgml を）をオー
  プンする際、起こっているのは以下のようなことです：

  カーネルは、（ルート・パーティションにある） Unix ファイルシステムから
  検索を開始します。そこに 'home' と呼ばれるディレクトリがあります。普通
  'home' は他のところにある大きなユーザー・パーティションへのマウントポ
  イントで、まずそこへいきます。そのユーザー・パーティションのトップレベ
  ルのディレクトリ構造において 'esr' というエントリがあるので、そのｉ-ノ
  ード番号を抽出します。そのｉ-ノードへ行き、それがディレクトリ構成であ
  ることを知り、次に 'WWW' を探します。その ｉ-ノード番号を抽出し、対応
  するサブディレクトリに行き、'ldp' を探します。そこもまたディレクトリの
  ｉ-ノードです。それをオープンし、'fundamentals.sgml' のｉ-ノード番号を
  探します。そのｉ-ノードはディレクトリではなく、そのかわりそのファイル
  に関連するディスクブロックのリストを保持しています。

  8.5.  どうして動作がおかしくなるのでしょう？

  前に、ファイルシステムは壊れやすいものであるとほのめかしたことがありま
  したね。ここで私たちは、ファイルを得るためには、気まぐれな長いチェイン
  をもつディレクトリやｉ-ノード参照の迷路の中で、石けり遊びみたいなこと
  をしなければならないことが分かっています。ここで、あなたのハードディス
  クに悪いところがあることが明るみに出たとします。

  運が良ければ、いくつかのファイルのデータを壊すくらいですむでしょう。運
  が悪ければ、ディレクトリ構造やｉ-ノード番号に矛盾が生じ、あなたのシス
  テムのサブツリー全体を奈落の底に落とすことでしょう。あるいはさらに運が
  悪ければ、ファイル構造体が乱され、一つのディスクブロックや i-ノードへ
  の参照がダブってしまったりするかもしれません。このような乱れは正常な
  ファイル操作にも広がり、もともとは正しい場所にあったデータまでも次々と
  破壊されてしまいます。

  幸いにもこのような偶発的な事故は、ディスクのハードウェアの信頼性が上
  がってきたために、非常に少なくなってきました。それでもなお、間違った個
  所がないことを保証するために、Unix が定期的にファイルシステムの整合性
  を取りたいと考えることも無理のないことです。最近の Unix は、ブート時
  （マウントする直前）に各パーティションに対して高速な整合性チェックを行
  います。また、何回かブートするごとに、より詳細なチェックを行うので、こ
  の際は多少時間がかかります。

  こんなことを聞けば、Unix とは恐ろしく複雑でトラブルが起こりやすいもの
  のように感じるかもしれませんが、これらブート時のチェックは、実際に被害
  に合う前に検出可能な問題を見つけたり修正したりすることにより、ユーザー
  を安心させるためなのです。他のオペレーティング・システムにはこういった
  機能はなく、ブート処理の速度をちょっとばかり向上させる代償に、ユーザー
  がびくびくしながら手作業で修復しようとせざるを得ないことを強いていま
  す(要するに、最初からノートン・ユーティリティか何かのコピーを準備して
  おけ、ということですか)。

  9.  コンピュータ言語っていうのはどうやって動くの？

  すでに``プログラムはどうやって動くのか''については説明しました。どのプ
  ログラムも究極的には、そのコンピュータのマシン語命令のバイト・ストリー
  ムとして実行しなければなりません。しかし人間はマシン語をうまく処理する
  事ができません。たとえハッカーの間でさえも、これをやるのはたぐいまれな
  ブラック・アートです。

  カーネルそのものの中にある、ハードウェアへの直接のインターフェースをサ
  ポートする少量のコードを除けば、現在ではほとんどすべての Unix コードは
  高水準言語で書かれています（ここで言う高水準とは、歴史的ななごりで、こ
  れら高水準言語を '低水準' のアセンブラ言語と区別するためのものです。後
  者は基本的にはマシンコードを包む薄い包み紙（ラッパー）です）。

  いくつかの異なった種類の高水準言語があります。これらを説明するために、
  ちょっと難しい話につきあっていただけたらと思います。プログラムのソース
  コードはある種の翻訳系を通して、マシンが実際に実行することのできるマシ
  ンコードに落とされます。

  9.1.  コンパイル言語

  従来のほとんどの言語はコンパイル言語です。コンパイル言語はコンパイラと
  呼ばれる（論理的に十分な名称です）特別なプログラムによりバイナリのマシ
  ンコードとしての実行ファイルに変換されます。いったんバイナリが生成され
  ると、再びそのソースコードを参照することなく、直接そのバイナリを実行す
  ることができます（ほとんどのソフトウェアはコンパイルされたバイナリとし
  て提供されており、そのコードをユーザーが見る事はありません）。

  コンパイル言語は高いパフォーマンスを示し、かつほとんど完璧な OS へのア
  クセスを提供しますが、それだけプログラムを書くのは難しくなります。

  C 言語は、Unix 自体もそれで書かれていて、これらコンパイル言語の中で
  （その変種である C++ と共に）断然最も重要です。FORTRAN は、これもコン
  パイル言語で、技術者や科学者の中でいまだ根強く使われていますが、古く、
  かつより原始的です。Unix の世界で主に使われているのはこれくらいで
  す。Unix 以外の世界では、金融やビジネス用のソフトウェア用に COBOL が非
  常に広範囲で使われています。

  その他多くのコンパイル言語が使われてきましたが、それらのほとんどはその
  生命を終えたか、または厳密には研究ツールになっています。もし新しい
  Unix 開発者になってコンパイル言語を使うのであれば、これはもう徹底的に
  C や C++ にするべきです。

  9.2.  インタプリタ言語

  インタプリタ言語はインタプリタ・プログラムに依存しています。これはソー
  スコードを読んで、それをその場で逐次翻訳し、計算をしたりシステムコール
  をしたりするものです。そのコードを実行するたびに、そのソースは毎回解釈
  され（かつ、そのインタープリタが存在し）なければなりません。

  インタプリタ言語は一般的にコンパイル言語より低速で、またオペレーティン
  グ・システムやハードウェアへのアクセスを制限される事も多々あります。一
  方、インタプリタ言語はプログラムを書くのが容易で、コンパイル言語に比べ
  てコーディング・エラーにも寛容です。

  シェルや bc(1) や sed(1) や awk(1) といった多くの Unix ユーティリティ
  は、実際上はインタプリタ言語です。BASIC も普通インタプリタです。Tcl も
  そうです。歴史的に、最も重要なインタプリタ言語は LISP でした（成功した
  ものの中でもっとも発展してきました）。今日では Perl が非常に広範囲で使
  われており、着実に評判を上げてきています。

  9.3.  P コード言語

  1990 年以来、コンパイルと逐次翻訳の両方を使う混成言語がだんだんと重要
  になってきています。Pコード言語は、ソースが実際に実行するコンパクトな
  バイナリにコンパイルされるところはコンパイル言語に似ていますが、その形
  式はマシンコードではありません。その疑似コード（またはP コード）は普通
  非常に単純ですが、本来のマシンコードよりパワフルです。そのプログラムを
  動かすと、P コードが解釈されます。

  P コードはコンパイル言語に近い速度で動作できます（P コード・インタプリ
  タは非常にシンプルに作成でき、小さく高速です）。しかし P コード言語は
  良いインタプリタの柔軟性とパワーを保ちます。重要なP コード言語には
  Python や Java があります。

  10.  インターネットはどうやって動いているの？

  インターネットがどうやって動いているのかを理解するのを助けるために、あ
  なたが典型的なインターネットの操作をしたときに何が起こっているのかにつ
  いて見ていきましょう −−− the Linux Documentation Project の Web 上
  にあるホームページで、このドキュメントの先頭ページをクリックしたとしま
  す。このドキュメントは

  http://sunsite.unc.edu/LDP/HOWTO/Fundamentals.html

  で、これはホスト sunsite.unc.edu の World Wide Web エクスポート・ディ
  レクトリにある LDP/HOWTO/Fundamentals.html にあることを示しています。

  10.1.  名前とその位置

  あなたのブラウザがまずしなければならないことは、そのドキュメントがある
  マシンへのネットワーク・コネクションを確立することです。これを行うため
  にはまず、ホスト sunsite.unc.edu のネットワーク的な位置を見つけなけれ
  ばなりません（'ホスト' とは sunsite.unc.edu は典型的なホスト名です。こ
  れに対応する位置は、実際にはIP アドレスと呼ばれる番号です（この用語の
  中の 'IP' 部分については後述します）。

  これを行うため、ブラウザはネームサーバと呼ばれるプログラムに対して問い
  合わせを行います。ネームサーバはあなたのマシン上にあるかもしれません
  が、あなたが対話しているサービス・マシン上で動いている可能性の方が高い
  でしょう。ISP に接続の申し込みをする時、セットアップ手続きの一部におい
  て、ほぼ間違いなく、インターネット・ソフトウェアに対してその ISP の
  ネットワーク上のネームサーバのIP アドレスを教えてやる必要があります。

  異なったマシン上のネームサーバは、お互いに対話し合って、ホスト名を解決
  する（ホスト名を IP アドレスにマッピングする）ために必要なすべての情報
  を交換し、最新に保つようにしています。あなたのネームサーバ
  は、sunsite.unc.edu を解決するために、ネットワークをまたがって３つか４
  つのサイトに問い合わせを行っているかもしれません。しかし、通常これは
  （１秒以内とかの）あっという間に行われます。

  ネームサーバはあなたのブラウザに対して、Sunsite の IP アドレスは
  152.2.22.81 であることを教えます。これを知ると、あなたのマシンは
  sunsite と直接ビットの交換を行う事ができるようになります。

  10.2.  パケットとルータ

  次にここでブラウザがやりたいのは、Sunsite の Web サーバに対して以下の
  ようにコマンドを送る事です。

  GET /LDP/HOWTO/Fundamentals.html HTTP/1.0

  これが実際に起こっていることです。コマンドはパケットとして送られます。
  これはビットのブロックで、３つの重要なものといっしょに電報のように包ま
  れています。重要なものとは、これが World Wide Web のリクエストであるこ
  とを示す送り元アドレス（あなたのマシンの IP アドレス）、宛先アドレ
  ス(152.2.22.81)およびサービス番号またはポート番号（この場合は 80）で
  す。

  その後あなたのマシンはそのパケットをケーブル（ISP へのモデム接続、また
  はローカルなネットワーク）へ送り、そのパケットはルータと呼ばれる特殊な
  マシンに届きます。ルータは自分のメモリ内にインターネットの地図を持って
  います。その地図は必ずしも完全なものではありませんが、あなたのネットワ
  ークに隣接する部分までを完全に網羅したものなので、ルータはそのパケット
  を、インターネット上の他の場所にあるルータへどう届ければよいかが分かっ
  ています。

  あなたのパケットは、宛先に届くまでの経路において、いくつかのルータを
  通っていくかもしれません。それら相互のルータは、相手のルータがパケット
  を受信したことを認識するために、どれくらい送信に時間がかかっているかを
  監視します。それらはその情報を、高速なリンク上の直截なトラフィックに対
  して使用します。それらルータはこの情報を使って、他のルータ（またはケー
  ブル）がネットワークからはずれてしまったことを検出し、その場合可能であ
  れば他の経路を見つけて経路情報を補正します。

  インターネットは核戦争を生き残るために設計されたという都市伝説がありま
  す。これは真実ではありませんが、インターネットの設計は、不確実な世界に
  おける変わり者のハードウェアから信頼できる能力を得るためには非常に優れ
  たものです。これは直接的に、インターネットの情報が（電話ネットワークの
  ような）少数の大規模なスイッチにではなく、何千というルータを通して配分
  されたという事実のおかげです。

  いったんあなたのパケットが宛先のマシンに届くと、そのマシンはサービス番
  号を使ってそのパケットを Web サーバに入力します。Web サーバはコマンド
  パケットの送り元 IP アドレスを見て、どこに応答を返せばよいかがわかりま
  す。Web サーバがこのドキュメントを返す時、それは数多くのパケットに分割
  されます、それらのパケットのサイズは、ネットワークにおける伝送メディア
  やサービスのタイプにより異なります。

  10.3.  TCP と IP

  複数パケットの転送がどうやって処理されるのかを理解するには、インター
  ネットが実際には、階層構造になっている２つのプロトコルを使っている事を
  知る必要があります。

  下位のレベルであるIP (Internet Protocol)は、個々のパケットを送信元から
  宛先に送る方法を知っています（このことから、これらの２つのアドレスは
  IP アドレスと呼ばれているのです）。しかしながら、IP には信頼性がありま
  せん。あるパケットが失われたり脱落してしまったりしても、送信元や宛先の
  マシンにはこのことには気づきません。ネットワークの専門用語では、IP は
  コネクションレスなプロトコルです。送信者はパケットを受信者に対して送り
  つけるだけで、そのACK(肯定応答)を求めません。

  しかしながら IP は高速かつ単純(cheap)です。高速で手軽で信頼性がなくて
  も構わない場合もあります。ネットワーク対応の Doom や Quake （訳注：両
  方ともゲームの名前）をしているとき、各々の弾丸は IP パケットとして表現
  されます。これらのうちのいくつかがなくなってしまっても、それはＯＫです
  よね。

  上位レベルのTCP（Transmission Control Protocol ＝伝送制御プロトコル）
  では信頼性を提供します。２つのマシンが TCP で送受信を行う際、受信側は
  送信側に対して ACK パケットを返します。送信側は一定時間内に ACK パケッ
  トを受信できないと、そのパケットを再送します。しかも、送信側は各 TCP
  パケットにシーケンス番号を付けて、もし（分割されたパケットが）順番に届
  かなかった場合、受信側でパケットを再構成することができるようになってい
  ます。（これは、接続中にネットワーク・リンクが確立したりダウンしたりす
  る場合に起こります。）

  TCP/IP パケットにはまた、不良のリンクによるデータの破損を検出できるよ
  うにチェックサムが設けられています。このため、TCP/IP とネームサーバを
  使っているユーザーから見ると、ホスト名／サービス番号のペアの間には信頼
  できるバイト・ストリームの経路があるように見えます。ネットワーク・プロ
  トコル（のソフトウェア）を書く人たちにとっては、これより下層レベルで行
  われるパケット化やパケット組み立て、エラーチェック、チェックサムの生成
  やチェック、再送といったことに関するすべてのことを考える必要はまずあり
  ません。

  10.4.  HTTP、あるアプリケーションプロトコル

  ここで前の例に戻りましょう。Web ブラウザとサーバは、TCP/IP の上位で動
  作するアプリケーションプロトコルで話をします。これは単にバイト文字列を
  やり取りするという単純な方法です。このプロトコルはHTTP (Hyper-Text
  Transfer Protocol)と呼ばれていて、そのコマンドのうちの１つが前に紹介し
  た GET コマンドです。

  GET コマンドは sunsite.unc.edu の Web サーバにサービス番号 80 といっ
  しょに届き、そのサーバ上でポート 80 番を監視しているサーバ・デーモンに
  渡されます。インターネット上のサービスのほとんどはサーバ・デーモンによ
  り実装されていて、これは単にポート上で入力を監視し、入ってくるコマンド
  を実行しているだけです。

  インターネットの設計がある包括的なルールを持っているとすれば、それはす
  べてのパーツが可能な限りシンプルで、かつ人間が見てわかるようになってい
  るということです。HTTP およびその関連プロトコル（ホスト間で電子メール
  を送るのに使われる Simple Mail Transfer Protocol,SMTPなど）は、キャ
  リッジ・リターン（訳注：復帰コード）／ライン・フィード（訳注：改行コー
  ド）で終わるシンプルな表示可能テキストによるコマンドを使う傾向がありま
  す。

  これはあまり役に立たない例です：環境によっては、ガチガチにコード化され
  たバイナリ・プロトコルで速度をかせぐことがあります。しかし経験上は、コ
  マンドを持つということで人間にとって解析し理解することが容易となり、ト
  リッキーであいまいにすることに伴うコストに比較して、目に見えない利益を
  得られるという恩恵にあずかれることが分かっています。

  HTTP/1.1 200 OK
  Date: Sat, 10 Oct 1998 18:43:35 GMT
  Server: Apache/1.2.6 Red Hat
  Last-Modified: Thu, 27 Aug 1998 17:55:15 GMT
  Content-Length: 2982
  Content-Type: text/html

  これらのヘッダに続いて１つの空行があり、その後（コネクションが切られる
  まで）Web ページのテキストが続きます。あなたのブラウザは単にそのページ
  を表示するだけです。ヘッダはブラウザに対して、その表示方法を指示します
  （代表的なものとして、Content-Type ヘッダは返されたデータが本物の HTML
  であることを伝えます）。

  11.  和訳版の校正

  11.1.  翻訳の校正

  長谷川 靖  yaz-hase@qb3.so-net.ne.jp、
  早川  仁   uv9h-hykw@asahi-net.or.jp、
  中野  武雄 nakano@apm.seikei.ac.jp、
  Akira Endo akendo@t3.rim.or.jp

  11.2.  SGMLのチェック

  中谷千絵   jeanne@mbox.kyoto-inet.or.jp

