近頃の若い者は軟弱でなっとらんので、ここらでひとつお手本を示すことにする。
↑といった意図はない。
世の中には根性あふれる若者がたくさんいるので、そういう人たちの邪魔にならないようにちょっとはずれたあたりで、多少は資料価値のあることを記録しておこう、とかその程度のつもりである。
本項はカーネル/VM Advent Calendarの何日目だかよくわからないがそもそも数えてもあんまりが意味ない日数目の記事である。 関連の深い2238クラブの別館として配置したが、独立した記事として読めるよう配慮した。つもり。だが無保証。
本項では1975年にBell研究所からリリースされたPDP-11上で動作するUNIX第6版(以下、v6と略)の配布用媒体であり、インストール時に使用する磁気テープのソフトウェア的な構造とその背景について解説する。 読者としては、UNIXとその歴史について多少の程度の知識と興味のある人を想定する。 UNIX第6版の特徴や経緯については2238クラブ等を適宜参照のこと。
磁気テープとは細長い樹脂に磁性体を塗布し、磁気による情報の記録媒体としたものである。 v6の配布に使用されたのはおもにTU10という装置用のDEC magtapeである。 テープは幅1.27cm、厚さ0.00254mm、長さ約732mのポリエステル樹脂で、直径約25cmのリールに巻き取って使用する。 1cmあたり315byte、1巻に約22Mbyteのデータが記録できた。
v6の配布データのサイズは6Mbyteほどなので、1巻に余裕をもって収まる計算になる。 UNIXが使いたい人はテープをBell研究所に送りつけてインストール用テープをコピーをして送り返してもらう、という方法をとっていた。
一方、読み書きする装置であるTU10は家庭用の中型の冷蔵庫くらいの大きさで、表面のフタをあけると上述のふたつのリールをはめ込む箇所と、磁気ヘッド、そしてテープ送りの装置があった。
TU10を使うときにはリールからテープを引き出し、磁気ヘッドを経由して巻き取り用のリールにつなげる。テープの走行に合わせて磁気ヘッドが情報を読み書きすることは言うまでもない。
当時の標準的なディスク装置RK05の容量は約2.5Mbyteである。1セクター512byteで4,096以上のセクターが作成可能だった。UNIXでは最初の4,000セクターのみ使用して、
RK05はカートリッジ式であったことや、ディスクの直径が36cmもあったことなど細かい違いはあるが、原理そのものに現在のハードディスクと本質的な違いはない。
配布用磁気テープは12,100セクターからなり、上記の3種類のディスクイメージが第101セクターから4,000セクターづつ格納されている。v6のインストールとは、それぞれのイメージをテープからディスクに書き込んで、必要な調整を行う、ということになる。
ここから先はv6のドキュメント「SETTING UP UNIX」のとおりである。 PDP-11を起動して、テープ用のboot romがある場合はそのアドレスから実行するよう、そうでない場合はブートローダーを直接入力する。 これによりテープの最初のセクター(512byte) がメインメモリー上に読み込まれるので、実行を移す。 そうすると`=’というプロンプトが出てくる。
ここでコマンドを入力することにより、磁気テープからディスクへのコピーを行う。 標準の構成だとコマンド名は「tmrk」で、テープの第100セクターからディスクのセクター0へ1セクター分、さらにテープのセクター101からディスクのセクター1へ3999セクター分コピーする。 鋭い読者はすでにお気づきのように、領域が連続しているので本来2段階にわける必要はない。 前述のガイドを見るとわかるが、機器構成によっては領域が連続しないので記述をわけてある、ということのようだ。
起動用ディスクを作成したらそこからUNIXを起動して残りの作業をおこなう。 そこから先は通常のUNIXの操作なので、ここではこれ以上触れない。
注意が必要なのは、エミュレーター等で実行した場合、tmrkは
すぐに操作が終わってしまって何がなんだかよくわからないおまじないにしか見えないということである。 実機で操作していると、テープが早送りや巻き戻しによってシークするし、巻かれているテープの量を見ればデータのおおよその位置がわかるなど、何が起こっているかを体験できる。 本項の導入部で磁気テープについてしつこく記述したのは、そのへんの感覚を多少なりとも補おうと思ってのことである。 が、所詮は畳の上の水練にすぎないのが残念。
さて、本論に戻ろう。
ここでは「tmrk」のような変な名前のコマンドに注目する。 ガイドをよく読むと、テープがTU16の場合は「htrk」、ディスクがRP03の場合は同様に「tmrp」か「htrp」、RP04だと「tmhp」か「hthp」となる。 ここまでくると読み出し側の磁気テープ装置名と、書き込み側のディスク装置名(のUNIXでのニックネーム)を2文字づつ組み合わせてコマンド名にしていることがわかる。
「tmrk」のようなコマンドを実行するときUNIXカーネルは存在しない。 したがって、コマンドはすべてカーネルなしに動作するスタンドアロンのプログラムでなければならない。
UNIX Version 6のソースコードにはmdecというディレクトリーがあって、ここにスタンドアロンのプログラムのソースコードがすべて格納されている。 実際に生成されるコマンドはrunというファイルを見るとわかる(当時はmakeがなかったので、コンパイル手順をシェルスクリプトで記録していた)。
ずいぶんいろいろファイルを作っているが、よく観察すると規則性はあきらかである。 tm(m), tc(t), ht(h)が磁気テープ装置3種類に、rk, rp, hpがハードディスク3種類に対応する。 これをもとに整理すると以下のような種類のファイルがある。
組み合わせ上すべてのファイルが用意されているわけではないのが不思議だが、詳細は不明。 このほか、テープやディスクの先頭のセクターに格納してプロンプトを出力するコードも用意されている。
ディスクからUNIXをブートする機構が、テープからコマンドを起動する機構と同様に扱われている、というわけである。 UNIXのブートストラップについては優れた解説がある。 あわせて読むと楽しさも倍である。
ここで出てくる疑問は「コマンドはどのようにテープに格納されているのだろう」ということで、実は「コマンドはプロンプトからどのように実行されるのだろうという疑問と等価である。 その答えは、「tpを使う」ということになる。
tpとは磁気テープをストレージとするアーカイブコマンドtp(1)とアーカイブ形式tp(5)の総称である。 tpではフラットにファイルを格納することができる(すなわち、ディレクトリー構造をもたない)。 ファイルにアーカイブを作るのが当然の最近のアーカイバーと違って、アーカイブは基本的にテープ上につくられることに注意。 しかも、tpでアーカイブを作ると、テープの先頭のセクターには簡単なプログラムが格納される。このプログラムを実行すると、`=’というプロンプトを表示する。 ここでファイル名を入力すると、tpのアーカイブの中からそのファイルを探し出してメモリ上に読み込んで実行を移す。 つまり、ファイルをコマンドとして実行する。 コマンドの実行が終わると、再びプロンプトに戻る。 これはもう簡単なオペレーティングシステムと言ってもよい。
v6の配布用テープの作成に当たっては、tpコマンドでスタンドアロンプログラムを集めて先頭部分を作り、そこに順次ディスクイメージを継ぎ足す方法をとっている。 つまり、インストールのときはtpアーカイブがプロンプト`=’を表示し、スタンドアロンプログラムを選択してディスクイメージのコピーを行っていた。
筆者が調べ始めてからこの結論にたどり着くまではずいぶん時間がかかった。 わかってみると実に単純ですぐにわからなかったのが不思議な気もするが、アーカイバーとローダーの統合は決して自明ではない。UNIXの偉大な単純化の一例である。
磁気テープは後にカセットテープのように、ふたつのリールをテープとともにカートリッジ中に内蔵するようになり、現在もDDS等として存在する。
また、磁気テープ以前には記憶媒体としての紙テープも存在した。 磁気テープに比べると記録密度が桁違いに低いことや、書き直しができないことなど制限が大きいため、v6のころはすでに使われていなかったようである。
tp(1)はあきらかにシステムに依存していた。 依存性の小さい、おなじみtar(1)が登場するのは1979年のUNIX第7版である。 マニュアルを読み比べると、tar(1)がtp(1)を意識しているのがわかる。
第6版から第7版のあいだにUNIXの様々な要素でシステム依存部分が整理されて、移植性が飛躍的に向上した。 これがUNIXの中世の幕開けである。 そのかわり、システムとの緊密な連携がゆるんでしまったのも事実である。 そういった意味でも、UNIX第6版は古代のUNIXの最終版として実に味わい深い。
tpによる配布用テープ作成法は最初のVAX用UNIXであるUNIX/32vでも踏襲されている。 このブート方式はVAX本来の方式とは異なっており、さまざまな面倒のもとであった。 そのため、後にはVAX固有のブート方式に合わせるよう改変された。
UNIX/32vのオリジナルの配布用テープは失われて、現存しているのはそこから取り出した個々のデータのみである。 UNIX/32vをエミュレーター上で動作させようと思い立った筆者は、まず、配布用テープを復元するところから出発した。 そのためにすでに復元に成功していたVAX用の最初のBSDシステムである3BSDを使用した。 tpの仕組み自体は同じだが、セクターサイズが異なるなど3BSDのtpアーカイブそのままではUNIX/32vの配布用テープは再現できない。 そこで、3BSDで生成したtpアーカイブをUNIX/32v用に変換するプログラムを作成した。 現在UNIX/32vの配布用テープとして流通しているのは、こうやって筆者が復元したものである。 実行に支障のない細部は手を抜いたため、 オリジナルと異なっていることはほぼ確実である。 だが、それを実証することはもはやかなわないのが残念である。
スタンドアロンの仲間に、ひとつだけdldrという、上記のパターンに当てはまらないコマンドがある。 ソースコードをさわりだけ見てみよう。
/ copy and execute DEC loaders core = 24. prs = 177550 mov $dldr,r0 mov $[core*2048.]-300,r1 mov r1,r2 1: mov (r0)+,(r1)+ cmp r0,$end blo 1b jmp (r2) dldr: 10706 24646 10705 62705 114 5001 13716 177570 (以下略)冒頭のコメントから見るに、DEC loaderというものがどこかに存在して、それを実行するためのもののようだ。 最初がリロケーションのためのコピーなのは定石どおり。 途中から、マシンコードがそのまま貼りつけてある 。
このコードが何をやっているかを知るには、逆アセンブルするしかない。 命令表をにらみながら自力で解くのもよいし、simhのようなエミュレーターに備わっている逆アセンブラーを使うと簡単である。 というわけでここから先は読者のためにとっておくとしよう。
おしまい。