データ収集や制御におけるデバイスへの入出力
高エネルギー物理学実験で検出器からのデータ収集や加速器制御に
VMEやCAMACなどをベースにした標準回路を使用します。
これらの標準回路は計算機に接続され、計算機は
一連の操作でそれらの回路からデータを収集したりそれらの回路へパラメータを設定
したりします。これらの操作はミクロな視点からみると細かな複雑な操作を必要と
しますが、マクロな視点から見ると明確でわかりやすい操作の一連の手順
(サブルーチン)としてとらえることができます。
マクロからミクロへはいくつかの階層から成るととら
え、それらの層はハード/ソフトの組み合わせの中で作られます。厄介なこと
にそれらの層で用いられる言葉はしばしば明確に定義されることなく
用いられるため混乱を起こします。
例えば、DMA(Direct Memory Access)とブロック転送は
いい例です。しかし、デバイスドライバの作者は書いている内に
何をしているのかわからなくなってしまわないために、
これらの定義をあいまいにすることなく明快にしておく必要があります。
計算機はハードの面から見ると、多くはCPUとメモリと入出力装置がバスによって
結び付けられる構造をとります。CPUに近い所と入出力に近い所で異なったバス規格
をとることによって、高速なCPUアーキテクチュアからより低速なI/Oアクセスを
効率良く行なうことができたりします。主にアナログ信号を処理するのに用いられる
CAMACは入出力装置に近い所のバスに属します。ディジタル信号を処理するのに
適しているVMEはCPUに近い所にも入出力に近い所にも使用されます。
最近はCPUが高速になって、I/Oバスと位置付けられるように
なってきました。VME上のCAMACインターフェイスを用いCAMACデバイスドラ
イバを書こうとするとVME/CAMACの理解、CAMACインターフェイスの操作
手順、CPU側にあるPCIやUSBなどの理解が前提となります。
ソフトの面からみると、ユーザが使う操作の一連の手順(サブルーチン)はオペ
レーティングシステム(OS)と呼ばれる基本ソフトの上で動作します。OSは細かく見て
いくと、さらにいくつかの階層から成っています。
UNIXの標準的な入出力操作を考えると、
ユーザが発行する入出力要求はデバイスと呼ばれる抽象化された対象に対して、
CAMACの場合で言えば、CAMACデバイスに対して、データの読みだしと言う入出力
要求を行なうことになります。
この要求はデバイスの種類に依存しない、より一般的な形
を取ってOSに渡されます。この要求はさらにOSの次のレベルであるデバイスドライバに
渡されます。デバイスドライバは渡されたパラメータに従って、CAMACの読み出しに必
要な操作を行ない、データを得て、それをOSの上位層に返します。
OSはそれを一般的なシステム関数の形でユーザに渡します。
こうすることでユーザはCAMACの読み出しが可能と
なっています。このようにデバイスドライバの作者はOS上でのユーザプログラムばかり
でなくOSの振る舞いやデバイスドライバ構造をよく知ることが必要です。この入門
書で扱うOSはLinuxで、Linuxはたくさん種類があるUNIXの1つです。
ただし、UNIXと一言で言ってもその内部仕様はさまざまで、BSD系やSystemV系
では異なってきます。デバイスドライバの仕様も同じではありません。
Linuxデバイスドライバを独自に学ぶ必要があります。
デバイスに対する基本操作
- プログラムI/O(Programmed I/O, PIO)操作
- ダイレクトメモリアクセス(Direct Memory Acess, DMA)操作
- 割り込み操作
デバイスに対する基本的な操作には3つあります。1つはプログラムI/O
と呼ばれるもので、CPUがアセンブラ命令に従い、
デバイスのレジスタにアクセスするものです。
CAMACやVMEなどのモジュールの各種レジスタ、例えばコントロール
ステータスレジスタをアクセスするのに用います。2つめはダイレクト
メモリアクセスと呼ばれるものです。
それは大量なデータをCPUの介在無しにアクセスする方法です。
DMAの起動にはPIOを用いて初期設定をしてあげる必要がありますが、
一度起動されるとPIOと違ってCPUは介在しません。大量で高速データ
転送を要求するVMEのメモリ読みだしにはこの方法を使うことで
性能が飛躍的に向上します。3つ目は割り込み(interrupt)です。
計算機外部から非同期にデータ処理要求を出す方法として利用されます。
例えば、データ収集における事象発生を知らせる計算機へのシグナルとして
これを使います。実際には検出器からのトリガー信号をCAMACやVMEの
I/Oモジュールに渡し、I/Oモジュールはそれぞれのプロトコルに従い、
計算機の割り込み機構を利用し、OSの介在の下、ユーザプログラムへ
知らされます。ですから、デバイスへのアクセスを考える場合、
これらの3つの操作法を確立すればよいのです。
オペレーティングシステム
オペレーティングシステム(Operating System, OS)によってデバイス
アクセスの方法は変わってきますが、仮想記憶を用いたものか
そうでないものかではその総さが大幅に異なってきます。
仮想記憶を用いたOSの場合はユーザプログラムの仮想アドレスを
物理アドレスやバスアドレスに変換するメカニズムを持つこととなり
複雑なものとなります。一方、仮想記憶を用いないOSの場合は
そのようなメカニズムを必要としないため、ユーザプログラムで
扱うアドレスはそのまま物理アドレスやバスアドレスになって
わかりやすいものとなります。しかし、仮想記憶を用いた
OSはユーザの不正なアクセスに対してシステムを守ることが
可能となり、より安全なシステム構築に適しています。
I/O命令とメモリ及びI/O空間
インプット/アウトプット(Input/Output, I/O)命令はCPUにより
その実装法が異なります。特別なI/O命令でデバイスにアクセス
する方法と特別な命令ではなくつまり実メモリと同じアクセス法が
あります。
PCIバスでは次の3つのアクセス空間を持ってます。
- メモリ空間
- I/O空間
- コンフィギュレーション(設定)空間
PCIデバイスのメモリ空間には実メモリへのアクセス法と同じ方法で
アクセスします。I/O空間や設定空間へは特別なI/O命令を用いて
行なわれます。
CPUがアクセスするアドレス空間には主記憶と呼ばれる実メモリ
空間、バスやI/Oデバイスが所有するバスアドレス空間があります。
一方、仮想記憶を用いたOSで扱う空間は次の3つです。
- 仮想アドレス空間
- 物理アドレス空間
- バスアドレス空間
仮想アドレスはアドレス変換機構によって物理アドレスに
変換されます。物理アドレスはそのまま実メモリを示す場合と
さらにバスアドレスに変換される場合があります。
ユーザスペースドライバとデバイスドライバ
デバイスドライバを実装する方法に2つの方法があります。
- ユーザスペースドライバ
- カーネルに組み込まれるデバイスドライバ
1つはデバイスへのアクセスを直接ユーザプログラムから行なう方法です。
例えば、デバイスにコントロールステータスレジスタがあるとします。
そのレジスタに1をセットするためにI/O命令を直接発行して行なったり、
実メモリへのアクセスと同じように1を書き込んだりすることで、
カーネルを介在させずにアクセスします。仮想記憶を用いたOSでは
mmapシステムコールのようなマッピングメカニズムを使って実現します。
また、仮想記憶を用いないOSではこの方法が簡単に実現できます。
もう1つの方法はカーネルを介在して行なう方法で、read/writeなどの
システムコールを使って実現されます。
ビックエンディアンとリトルエンディアン
CPUやバスのバイトオーダーにはビックエンディアン(Big Endian)と
リトルエンディアン(Little Endian)があります。
それらはMost Significant Byte(MSB)とLeast Significant Byte(LSB)が
それぞれ逆転しています。ですから、リトルエンディアンのCPUから
ビックエンディアンのバスをアクセスする場合、または逆の場合は
バイトオーダーに注意を要します。