検索

Google
Web www.icefree.org

RSS of recent changes

 

資料のページ

2017-06-20 (火) 23:23:54 (2494d)

NFS Client on X680x0 開発資料
 
■はじめに
 資料の中で NFS とあるのは、Network File System のことです。 NFS.x とあるのは、拙作の X680x0 上で動作する NFS Client のことです。

 最近、開発を久しぶりに再開したので資料が無いとわからないとか、ブラウザで資料を見ながらプログラミングというのが意外と便利だったとか、ネスケコンポーザを使うと楽に書けることがわかったとか、その他の理由からこのページの更新頻度が高くなっています。
 
 このページに関することで何かありましたら、 メールでお知らせください。 (別に掲示板でもなんでも良いのですが)
 
■RFC
 NFS とか RPC の仕様に関するものです。基本的な RPC のルーチンは NetBSD/pc98 から持ってきたものなので、直接必要になるのは NFS と MOUNT に 関するものです。
 RFC はいろいろな場所で配布されていますので、 サーチエンジンなどで検索して一番近いところから ダウンロードしてください。 一応うちのリンクページにもいくつかのリンクを用意してあります。
 
実際に良く使っているもの
・RFC1094 NFS:Network File System Protocol Specification
 NFS v2 の仕様です。Appendix で MOUNT PROTOCOL DEFINITION が付いてます。
・RFC1057 RPC:Remote Procedure Call Protocol Specification Version 2
・RFC1832 XDR:External Data Representation Standard
  
参考になるかもしれないもの
・RFC2055 WebNFS Server Specification
・RFC2054 WebNFS Client Specification
・RFC1831 RPC:Remote Procedure Call Protocol specification Version 2
・RFC1813 NFS Version 3 Protocol Specification
■ヘッダファイル
 rpc のヘッダファイルです。これで、RPCコールの引数の構造体がわかります。
・nfs_prot.h
・mount.h

■ローカルにある資料

 この下にあるリンクは、うちのローカルのHDDにあるファイルへのものなので、WEB上では見られません。
・ln_tech.doc

 
■Human68k 解析資料
 
■NFS.x についての資料

 まず、実際にNFS.xがどうやってネットワークドライブを実現しているかを説明します。

nfs_flow.png

基本的な流れ

(0)DOSコール
 ユーザプログラムがDOSコールを行います。これによりF例外が発生します。

(1)F例外
 DOSコール・浮動小数点演算に使用されるF例外をフックして、そこに来るコールの引数を調べます。それが、NFSドライブに関するものである場合には、(4)に行きます。

(2)lndrv (lndrv が常駐している場合)
 lndrv が常駐していると一部のDOSコールを lndrv がフックします。そこで、NFS.xはさらに lndrv の常駐部を書き換えます。そこでコールの引数を調べて、それがNFSドライブに関するものである場合には、(4)に行きます。

(3)通常のDOSコール
 正規のルーチンへ戻ります

(4)NFSコール
 NFS.xでDOSコールを処理した後、コールしたユーザプログラムに復帰します。原則的に正規のDOSコールは実行しません(一部例外あり)。

lndrv 対応ソフトでの流れ

(0)lndrv コール
 lndrv 対応ソフトが lndrv 内のテーブルを用いて、DOSコールを行います。このときは、F例外によるDOSコールではないので、F例外のフックは通りません。基本的な流れの(2)へと飛びます。

備考

 F例外と lndrv で2回同じチェックすることになります。これは、lndrv 対応ソフトがF例外による通常のDOSコールではなく、lndrv を使ってDOSコールを行うことへの対策からです。NFS.xがDOSコールを1つ1つフックするという方法もありますが、常駐物の常駐させる順番によってはうまく動作しなくなる可能性があるのと、フックする数が多くなることからF例外でまとめて処理しています。

 最後の Human68k である v3.02 ではもっと簡単にネットワークドライブを実現することができますが、v2.や v3.01 でも動作させたいのでこのような方法をとっています。

ハードリンクとシンボリックリンク

 ハードリンクはそのまま普通のディレクトリやファイルとして使用できます(逆に検出するほうが面倒です)。ただし、それぞれのファイルに割り当てられる固有の番号としての fileid がハードリンクだと同じ値になることがあるので注意が必要です。UNIX では、NFS の fileid = UNIX の iノード番号であることが多く、その場合は必ず同じ値になります。
 NFS.x では fileid を DOS_FILES などで利用しています。
 
 シンボリックリンクは NFS プロトコルにより自力で解決しなければなりません。

その他。謎のメモ
 db.x(v2.00) で実行すると、普通の実行に比べて アドレスが +$9900 になる。
 cookie は char[] で、nfs_fh は struct
 libc の bcopy, memcopy は領域が重なっていると 正しく転送できない。memmove を使えば正しく転送できる。
 
メモリ馬鹿食いの理由。
 原因は_FILES, _NFILES コールのためのバッファにあります。FILES,NFILESの組み合わせで1つのディレクトリなどに対応しているのですが、これらは複数組を同時に使うことができます。つまり、
FILES (1)
NFILES (1)
FILES (2)
NFILES (2)
NFILES (1)
などというように使用できます。Human68kの場合では、引数として使用されるバッファ内に、必要な情報が特定できるようになっています。NFS.xでもそのバッファを使っているのですが、必要な情報を格納するだけの大きさが足りないために、他にも専用のバッファを確保してあります。その構造は以下のようになっています。

struct 
{ 
    nfs_fh    handle; 
    nfs_fh    parent; 
    char    search_name[NFS_MAXNAMLEN + 1]; 
    char    dirname[NFS_MAXPATHLEN + 1]; 
} filescash[FILESCASHSIZE]; 

FILESCASHSIZE = 128
NFS_MAXNAMLEN = 255
NFS_MAXPATHLEN = 1024
また、nfs_fh は32バイトです。

というわけで、これだけで、(32+32+255+1+1024+1) * 128 = 172160 = 約168k になります。
 このバッファは古いものから順に上書きされていくのですが、FILESCASHSIZE -1 の分だけ、間に関係ないFILESコールが入っても正常に動作するようになっています。
 今は128になっていますが、v0.32以前は512でした。