ごく簡単に説明すると,プラグ&プレイはモデムやネットワークカー ド,サウンドカード等の各種ハードウェア(デバイス)を見つけられる場所を自 動的にソフトウェアに教えます.プラグ&プレイの仕事は,物理デバイス とこれを操作するソフトウェア(デバイスドライバ)と一致させ,デバイスとド ライバの間に通信「チャンネル」を作ることです.これを実現するために, PnP は以下の「バスリソース」をドライバとハードウェアの両方に割り当てます: I/O アドレス,IRQ, DMA チャンネル(ISA バスの場合のみ),メモリ領域. これら 4 つのバスリソースが何のことか分からなければ,この HOWTO の後の 節を読んでください.これらのバスリソースのうち 3 つに関する Linux Gazette の記事が Introduction to IRQs, DMAs and Base Addresses にあります.一度これらのバスリソースが割り当てられると(そして正しい ドライバがインストールされると),/dev ディレクトリにあるデバイスの ファイルが使えるようになります.
このようなバスリソースの PnP 割り当てが「設定(configuring)」と呼ばれ ることもありますが,これは低レベルな種類の設定に過ぎません.つまり, PnP を最大限利用した場合でもデバイスの設定の多くは PnP 以外で行われま す.例えばモデムの設定であれば,「初期化文字列」が I/O アドレスの 「チャンネル」を使ってモデムに送られます.モデムに文字列を送るために使 われる「チャンネル」は PnP が割り当てたものですが,「初期化文字列」そ のものは PnP とは無関係です.シリアルポートの速度(および他のパラメー タの多く)の設定は,ユーザが実行した(起動時に自動的に実行されることもよ くあります)プログラムからデバイスドライバへメッセージを送ることによっ て行います.この設定もやはり PnP とは関係ありません.このように,PnP の話題においては「設定」は特定の種類の設定に過ぎません.他の文書 (MS Windows 向けの文書など)ではバスリソースを「リソース」と読んでいる ことがありますが,この文書では他にもたくさんあるリソースと区別するため に,「バスリソース」という用語を使うことにします.
コンピュータは計算を行う CPU とデータを格納するメモリで 構成されています.これに加えて,各種ディスクドライブやビデオカード,キー ボード,ネットワークカード,モデムカード,サウンドカード,シリアルポー ト,パラレルポート等があります.また,電力を供給する電源ユニット,デバ イスを CPU に接続するマザーボード上のバス,そしてこれら全てを格納する ケースがあります.
昔はほとんど全てのデバイスには専用のプラグインカード(プリント回路基板) がありました.最近の多くの「デバイス」は,差し込むカードとしてだけでな く,「マザーボード」に取り付けられた小さいチップの集まりとしても提供さ れています.マザーボードに差し込むカードには 1 つ 以上のデバイスが入っ ていることもあります.メモリチップをデバイスとして考えることもあります が,本 HOWTO における意味でのプラグ&プレイではありません.
コンピュータシステムを正しく動作させるためには,それぞれのデバイスは 「デバイスドライバ」の制御下になければなりません.デバイスドライバはオ ペレーティングシステムの一部であり(モジュールとしてロードされることも あります),CPU 上で動作す るソフトウェアです.デバイスドライバは /dev ディレクトリにある 「特殊ファイル」に関連付けられています.このファイルは実際のファイルで はありません.このファイルの名前は hda1(ハードディスク a の最初のパー ティション),ttyS0(最初のシリアルポート),eth1 (2番目のイーサネットカー ド)のようになっています.混み入った話になるのですが,選択されるデバイ スドライバ(例えば eth1 とします)は使っているイーサネットカードの種類に よって決まります.つまり,全てのイーサネットドライバが eth1 を割り当て られるのではありません.取り付けたイーサネットカードの機種に対応する, ある特定のドライバが割り当てられなければなりません.デバイスを制御する ために,(デバイスドライバを制御している)CPU は各種デバイスにコマンド (およびデータ)を送ったり,情報を読み出したりします.このような通信を行 うため,各デバイスドライバは制御するデバイスの唯一のアドレス値を知って いなければなりません.このようなアドレス値を知ることが「通信チャンネル を設定する」ことなのです.この「チャンネル」が実際には PC 内部のデータ バスであり,他のほとんど全てのものに共有されている場合でも同じです. 実際の通信チャンネルはここでの説明より少し複雑です.「アドレス値」は実 際には幅を持ったアドレスですし,チャンネルには(割り込みとして知られて いる)逆向きの部分があり,デバイスはこれを使って緊急の「ヘルプ」要求を デバイスドライバに送ることができます.
PC には 3 つのアドレス空間(I/O, メインメモリ,(PCI バスに限り)設定) があります.これら 3 種類のアドレスは,PC 内部では同じバスを共有してい ます.しかし,あるアドレスがどの空間(I/O, メインメモリ,設定)のものか は,PC のバス上にある専用の配線の電圧を使って伝えられます.詳しくは アドレス の節を参照してください.元々は デバイスは I/O アドレス空間に配置されていましたが,現在はメインメモリ内の 空間を使うこともあります.I/O アドレスは単に "I/O", "IO", "i/o", "io" と呼ばれることもあります.また「I/O ポート」という言葉も使われま す.I/O アドレス(または割り込み等の他のバスリソース)は以下の 2 つの主なステッ プにより割り当てられます:
先程述べた 2 ステップの処理は,道で誰かの家の番地を見つける問題を 2 つ に分けたものと似ています.あなたは番地を見つけなければ(そして書き留め なければ)なりませんし,この家の持ち主は,見つけてもらえるように家の前に 番地を表示していなければなりません.コンピュータの場合には,デバイスド ライバはアドレスを取得しなければならず,デバイスのハードウェアは同じア ドレスを特定のレジスタに設定していなければなりません.この作業は両方と も行わなければならないのですが,片方しか設定しないようなミスをユーザが することがあります.このような場合には,コンピュータはデバイスを検出で きずに困ってしまうことになります.例えば,シリアルポートにアドレスを割 り当てる目的で "setserial" を使っても,"setserial" はドライバにしかア ドレスを教えません.setserial はシリアルポート自体のアドレスは設定しま せん.実際にシリアルポートがのアドレスが違っていたら(あるいは全く設定 されていなければ),誤ったアドレスをドライバに設定していることになり, 問題が起こります.
この他にも明らかに必要なこととして,あるアドレスをデバイスドライバが使 えるようになる前には,そのアドレスがカードに設定されていなければならな いことが挙げられます.デバイスドライバはコン ピュータが起動した直後に動作を始めることが多いので,PnP 設定プログラム がカードのアドレス設定を行う前にデバイスドライバが(カードがあるかどう かを調べる等のために)カードにアクセスしようとすることも時々あります. このような場合には,たとえカードがあっても(ただし,まだアドレスを持っ ていない),カードが見つからないというエラーメッセージが表示されます.
先の 2 つの段落での I/O アドレスに関する説明は,他のリソース( IRQ --概要, DMA チャンネル, メモリ領域 )についても同じように当てはまります.これらについては以下の 3 つの章で 説明します.
この説明を読んだ後にもっと詳しいことを知りたくなった場合には 割り込み --詳細を読んでください. ここでの説明はごく簡単に行います: アドレスの他にも,扱わなければな らない割り込み番号(IRQ 5 等)というものがあります.これは IRQ(Interrupt ReQuest, 割り込み要求)番号と呼ばれます.デバイスドライバが通信を行うた めにはカードのアドレスを知っている必要があることは既に述べました.しか し,逆方向の通信についてはどうでしょうか? また,デバイスがデバイスドラ イバに急いで伝えなくてはならないことがあるとしたら? 例えばデバイスは, メインメモリに送らなければならない大量のバイト列を受け取るようなことが あるかもしれません.このような場合には,デバイスはすかさずドライバを呼 び出してデータを一度に受け取り,バッファ一杯に詰まったデータを急いでメ インメモリに移してもらう必要があります.
デバイスはどのようにして助けを求めなければならないのでしょうか? メイン データバスは既に使われているでしょうから,これを使うことはできません. その代わりに,デバイスは専用の割り込み線(バスの一部です)に電圧を設定し ます.この線は多くの場合,そのデバイスのためだけに予約されています. この信号は割り込みと呼ばれます.割り込み線には等価な線が 16 個あり,こ れらはそれぞれ(間接的に)特定のデバイスドライバに繋がっています.それぞ れの線には固有の IRQ (Interrupt ReQuest)番号がついています.デバイスは 割り込みを正しい線に送らなければならず,デバイスドライバは正しい線で割 り込みを待たなければなりません.どの線に割り込みが起こるかはデバイスに 格納されている IRQ 番号によって決まります.監視する IRQ がデバイスドラ イバにわかるように,デバイスドライバにはこれと同じ IRQ 番号を設定しな ければなりません.
デバイスドライバが割り込み(助けの求め)を受け取ると,デバイスドライバは 割り込みが発行された理由を調べ,割り込みを処理する適切な動作を行わなけ ればなりません.ISA バスの場合には,それぞれにデバイスに固有の IRQ 番 号が必要です.PCI バスの場合と別の特殊な場合には,IRQ を共有することが できます.
DMA チャンネルを使うのは ISA バスだけです.DMA は 「Direct Memory Access(直接メモリアクセス)」という意味です.これはデバ イスが CPU からコンピュータのメインバスを引き継ぎ,バイト列を メインメモリへ直接転送をすることが許可されている場所です.通常は CPU はこのような転送を 2 ステップの処理で行います: (1) I/O デバイスのメモリ 空間から読み込んだバイト列を CPU そのものに送る.(2) このバイト列を CPU からメインメモリに送る.DMA を使うと,この処理はデバイスからメモリ へ直接バイト列を送るという 1 つのステップになります.ただし,デバイス のハードウェアにこの機能が組み込まれていなければならないため,必ずしも 全てのデバイスで DMA を使用できるわけではありません.DMA を行っている 間は CPU の動作は制限されます.なぜなら,メインバスが DMA 転送に使われ てしまうからです.
実は PCI バスには DMA がないのですが,その代わりに DMA よりももっと良 い機能があります.つまりバスマスタリングです.バスマスタリングの動作は DMA と似ており,DMA と呼ばれることもあります(例えば,"UltraDMA" と呼ば れるハードディスクドライブ).この機能を使うと,デバイスは一時的にバス の所有者(バスマスタ)になり,バスマスタが CPU であるかのようにバイト列 を転送することができます.バスマスタリングはチャンネル番号を全く使いま せん.なぜなら PCI バスの仕組みでは,PCI のハードウェアは現在のバスマ スタやバスマスタになろうとしてリクエストを出しているデバイスを知ること ができるからです.したがって,PCI バスに対する DMA チャンネルの割り当 てはありません.
ISA バス上のデバイスが DMA を行おうとする際,このデバイスは割り込み要 求によく似た DMA 要求を専用の要求線を使って発行します.実際には DMA は 割り込みを使って処理することもできるはずなのですが,そうすると遅延が起 こるため,DMA 要求と呼ばれる特別なタイプの割り込みを使う方が速いのです. 割り込みと同様に,DMA 要求には番号が付けられており,要求を行ったデバイ スを識別することができます.この番号は DMA チャンネルと呼ばれます.DMA チャンネルはメインバスを全て使う(また同時に 1 つしか動作できない)ので, 実際にはこれらすべてが同じチャンネルを使うのですが,「DMA チャンネル」 番号を使うと「チャンネル」を使っているデバイスを識別することができます. 各「チャンネル」の現在の状態を格納しているハードウェアレジスタがマザー ボード上にあります.このように,DMA 要求を行うためには,デバイスは物理 デバイスのレジスタに格納されている DMA チャンネル番号を知っていなけれ ばなりません.
一部のデバイスにはメインメモリ内のアドレス空間が割り当てられていま す.これは多くの場合「共有メモリ(shared memory)」または 「メモリマップト I/O(memory mapped I/O)」です.デバイス上の ROM である こともあります.バスリソースの議論をする時には,これは単に「メモリ」と 呼ばれます.このようなデバイスも I/O アドレス空間を使用します.
このようなカードを挿した時は,実際には(I/O メモリでなく)メインメモリに 対するメモリモジュールを挿していることになります.これは ROM(Read Only Memory)と共有メモリのどちらでも構いません.このメモリは デバイスとメインメモリ間の直接データ「転送」の手段として使われます. しかし,これは実際には転送ではありません.というのも,デバイスは自分自 身のメモリにデータを書き込み,それがメインメモリにも書き込まれたことに なっているだけだからです.カードとデバイスドライバのいずれも,この領域 がどこであるかを意識する必要はありません.メモリアドレスは多分非常に高 い位置に取られるため,低い位置にあるコンピュータのメモリチップのアドレ スと重なってしまうことはありません.
ROM の扱いは異なります.これはプログラム(多分デバイスドライバ)であるこ とが多く,デバイスと一緒に使われます.多分これは Windows 上だけでなく Linux 上でも動作します(??).これはシャドウ化する必要があるかもしれませ ん.シャドウ化と言うのは,高速な動作を行わせるために ROM の内容をメイ ンメモリにコピーすることです.一旦シャドウ化を行うと,この領域はもはや 「読み取り専用」ではなくなります.
このように,デバイスドライバは自分が制御するハードウェアに対して何 らかの方法で「割り当て」られなければなりません.これはバスリソース (I/O, メモリ,IRQ, DMA)を物理デバイスとデバイスドライバのソフトウェア の両方に与えることによって行います.例えば,シリアルポートは(4 つのう ち)2 つのリソース,すなわち IRQ と I/O アドレスしか使いません.この値 は両方ともデバイスドライバと物理デバイスに与えなければなりません.ドラ イバ(とそのデバイス)は /dev ディレクトリ内にも名前を与えられます(ttyS1 等).アドレスと IRQ 番号 は物理デバイスのカードのレジスタ内(またはマザー ボード上のチップ内)に格納されます.ジャンパの場合には,この情報は必ず デバイスのハードウェア(カード等)に格納されます.しかし PnP の場合には 通常,PC の電源を切るとレジスタのデータは無くなるので,リソースデータ は PC の電源を入れるたびに毎回,各デバイスに対して新しく与えなければな りません.
PC のアーキテクチャでは IRQ, DMA チャンネル,I/O アドレス,メモリ 領域の数に制限があります.仮にデバイスの数が少なく,これら全てが標準化 されたバスリソース(固有の I/O アドレスと IRQ 番号)を持っているならば,デバ イスドライバをデバイスに割り当てる際の問題は起こらないでしょう. コンピュータ上の各デバイスは他のデバイスと衝突しないような固定のリソー スを持てるからです.違うデバイスが同じ I/O アドレスや IRQ を持つことも ないでしょう.ですから,各デバイスドライバのプログラム中に I/O アドレ スやIRQ をハードコーディングすれば良いのです.とても話が簡単になりますね.
しかし,現実はそうではありません.最近では異なるデバイスがたくさんある ので衝突は良く起きますし,同じタイプのデバイスを複数使わなければならな い場合もあります.例えば,複数の異なるディスクドライブや複数のシリアル ポートを使いたい場合などです.このような理由のため,デバイスには衝突を 回避できるように, IRQ やアドレスを設定できるような自由度が必要となり ます.しかし,クロックやキーボードのような一部の IRQ やアドレスは標準 値が使われます.このようなデバイスにはこういった自由度は必要ありません.
バスリソース割り当ての衝突の問題とは別に,デバイスドライバのバスリソー ス設定を誤ってしまう問題があります.例えば,本当はデバイスに IRQ 5 が 設定されているのに設定ファイルには IRQ 4 と書いているような場合です. これは別の種類のバスリソース割り当てエラーです.
バスリソースの割り当てを正しく行えば,物理デバイスとこれに対応するデバイス ドライバの間に通信チャンネルが確立されます.例えば,ある範囲の I/O ア ドレス(リソース)がデバイスドライバとハードウェアに割り当てられた場合, 両者の間に一方通行の通信チャンネルが確立したことになります.ドライバは コマンドと情報をデバイスに送ることができます.ドライバはレジスタを読む ことによってデバイスから情報を取得することができるので,実際には単なる 一方通行というわけではありません.しかし,この方法ではデバイス側から通 信を始めることはできません.双方向通信チャンネルを作るためには,デバイス は IRQ を必要とします.双方向通信チャンネルとは,デバイスドライバからも デバイスからも通信を始めることができる通信のことです.
シリアルポートにケーブルで接続した外部デバイス(外付けモデムなど)も プラグ&プレイと呼ばれます.バスリソース(IRQ と I/O ポート)を必要と するのはシリアルポート自身だけなので,このような接続デバイス自体にバス リソースは割り当てられません.ですから,実際はこれらのデバイスには PnP は必要ではありません. そうであっても,このような外部シリアルデバイスに対しても PnP の仕様が 決められています.
PnP OS はこのような外部デバイスを検出し,そのデバイスのモデル番号等を 読み込みます.これにより,そのデバイス用のデバイスドライバを見つけるこ とができるので,特定のデバイス(例えば /dev/ttyS1)を使っていることをア プリケーションプログラムに対して指示する必要が無くなります.デバイスが 接続されているシリアルポートを(設定ファイル等を使って)手動で指定するこ ともできるはず(デバイスのモデル番号を指定することがあるかもしれません) なので,どうしても PnP の「シリアルポート」機能が必要だということはな いでしょう.