next up previous contents
Next: 割り込みの使い方 Up: VMEバスやCAMACをアクセスする Previous: 基本的な概念

VMEのメモリへの割付

VMEシステムの場合それぞれのモジュールはVMEメモリー空間に割り付けられ た読み書きの出来るメモリーとして扱われます。ワークステーションで通常使 われるメモリーシステムは仮想メモリーシステムです。ユーザプロセスで使わ れる論理アドレス空間はプロセスごとに全て同じように設計されます。計算機 のハードウエアはそれとは関係なく物理的なメモリー空間を持っています。例 えば32MBのメモリーは全てのバイトがユニークに指定できるように計算機バス にはアドレス線が必要な数だけ出ています。それに対してユーザプログラムは 例えばプログラムAもプログラムBも100番地から実行を開始するようにコンパ イルされているとします。ユーザがそれぞれプログラムを実行しようとすると カーネルはプログラムから見ると論理アドレス空間が使われているのを自動的 にCPUから外に出て行くときに物理アドレス空間になるようにテーブルを準備 しますが、プログラムAとBがぶつからないように面倒を見てくれます。これら の機能はメモリーマネジメントと呼ばれます。逆に共有メモリーを使うときは 同じところを見るようにテーブルを割り当ててくれます。VM Eの場合はさらに、 外部アドレスをVMEメモリー空間の特定の物理アドレスに固定して割り当てて もらわなければなりません。この作業は先に開いたVME特殊ファイルを用いて mmapシステムコールで行います。

        caddr_t vme_ptr;



        vme_ptr = mmap( 0, 0x400, PROT_READ | PROT_WRITE, 

                        MAP_SHARED, fd, ( off_t ) 0xc0000000 );

最初の引数0は、プロセスのアドレスですが、0を指定することによりシステム が最も適当なアドレスを割り当てるよう指示します。次の0x400はマッピング をおこなうメモリー空間のサイズで、バイト単位で与えます。今の場合16進 400バイトということになります。次は保護モードで、この例では読み書きと もに許されることになります。次のMAP_SHAREDはこのアドレスへ書き込むとそ れにより実際のVMEメモリーが変更されることを表わします(MA P_PRIVATEの場 合メモリーのコピーがプロセス用に作られそこが変更されることになり実際の VMEメモリーは変更されません)。次の引数は先ほど開いたファイル記述子です。 最後の引数0xc0000000はVMEの上でのアドレスです。

マップ出来るアドレスは任意に設定できるわけではありません。システム毎 にVMEアクセスの型毎に設定できる範囲が決まっています。また、マップされ るメモリーの境界はページサイズと呼ばれるメモリー参照の単位に切りすてら れます。ページサイズはgetpagesiz eシステムコールで取ることが出来ます。 次の例では半端なアドレスに置かれたモジュールを参照する場合を見ます。

        #define VMEMODULEADDR   0xc0000020



        off_t   vmeoffset;

        int     pagesize;



        pagesize = getpagesize( );

        vmeoffset = VMEMODULEADDR / pagesize * pagesize;



        vme_ptr = mmap( 0, 0x400, PROT_READ | PROT_WRITE, 

                        MAP_SHARED, fd, vmeoffset );

vmeoffsetがpagesize単位に丸められているのがわかります。

以後vme_ptrを使ってモジュールにアクセスします。終了時にアンマップす るときに必要ですのでポインターの値は保存しておきましょう。他のポインター にキャストしながらコピーしてそちらを使いましょう。参照が終わったときは アンマップしクローズします。

        munmap( vme_ptr, 0x400 );

        close( fd );



これでプロセスからは切り離されました。

 このようにVMEアクセスは基本的なシステムコールを利用してデバイスドラ
イバーを呼び出すことで処理できます。ですが、実用的にはそれぞれのデバイ
スドライバーは異なったVMEへのアクセスの仕方を提供しますから必ずしもす
べての計算機で互換なプログラムを書けるわけではありません。そこでKEKの
オンライングループではVMEアクセスをするための標準的な関数を用意してい
ます。新しいボードを持ってきても同じ手順でアクセスするようにインターフェー
ス関数を書けばユーザは同じコードをコンパイルしなおすだけでプログラムを
走らせることができます。

 この節で説明した機能はそれらのインターフェース関数に含まれているはず
です。実例は次のようになります。

\begin{verbatim}

        #include        <vmelib.h>



        caddr_t * vmebase;



        vmebase = vme_mapopen( VME_A24D16MODE );

        if( vmebase == -1 )     { /* マップに失敗 */ }

        ...

        vme_mapclose( );

互換性の高いプログラムを書こうとするときにはこうした関数を参照したほ うがよいでしょう。当然ですがvmelib.hとlibvme.aは必要です。



next up previous contents
Next: 割り込みの使い方 Up: VMEバスやCAMACをアクセスする Previous: 基本的な概念



Kinya Hibino
Sun Jan 14 21:36:40 JST 1996