64DD 開発ツール向け書込み用ライブラリ(libddwrite.a)技術資料 ver. 1.12 最終更新日 98/6/24 任天堂開発3部 橋田 貴之 I. この資料について この資料は、64DD 開発ツール向け書込み用ライブラリ(libddwrite.a)に関す る技術資料です。 II. 関数使用方法 下記に、libddwrite.a で使用できる追加関数を示します。なお、 libddwrite.a は libleo_d.a 相当を含んだ形になっていますので、 libleo_d.a の関数も通常通り使用することができます。 **ここにあげた全ての関数は、内部でメッセージキューを用いて割り込み待 ちをするため、これらをコールしたスレッドは関数内部で一旦待機状態になり、 より優先順位の低いスレッドに実行権が移ります。ご注意下さい。 **必ず libultra_d.a をリンクする前に libddwrite.a をリンクするように してください。 **他の一般に公開されている libleo_d.a の関数を使用する際は注意してく ださい。未使用のディスクに対してハングアップするからです。 なお、ヘッダファイルとして、ddwrite.h が提供されます。以下の関数 はこのヘッダファイルをインクルードすることで実行可能になります。 **ヘッダファイル ddwrite.h は必ず leo.h のあとにインクルードするよう にしてください。 ===================================================================== ・s32 ddWrite(DDCmd *command) ------------------------------------------------------------------ 引数の DDCmd 構造体で指定した値にしたがって、ディスクをライトします。 詳しくは下記の「DDCmd 構造体の説明」をご覧下さい。 返り値は0が正常終了、0以外が異常終了です。返り値は 64DD の通常のエラー コードと同じです。必ず返り値はチェックしてください。異常終了の原因と しては主にディスクが挿入されていない、等の(回復可能な)エラーが考えられ ます。 ===================================================================== DDCmd 構造体の説明 typedef struct{ u32 startLBA; s32 diskType; void *loadAddr; void *idAddr; u32 iplSize; void *writeBuf; u32 writeSize; s32 (*getdata)(void *, u32); u32 totalSize; u32 flags; void (*formatHook)(void); void (*infoHook)(DDInfo *); } DDCmd; startLBA ……… データを書きはじめるブロックを LBA で指定します。 diskType ……… ディスクタイプを指定します。現在のディスクタイプを変更 したくないときは -1 を指定してください。 loadAddr ……… ロードアドレスを格納します。変更したくないときは 0 を 指定してください。 idAddr ………… ディスク ID を指定します。このアドレスから32バイトが そのままディスク ID としてディスクに書き込まれます。変 更したくないときは 0 を指定してください。 iplSize ……… IPL サイズを指定します。ブロック数で指定することになり ます。もしここに 0 を指定した場合は下記のような動作に なります。 startLBA の指定が 0 の場合: writeSize から自動的に IPL サイズが計 算され、格納される。*注 startLBA の指定が 0 でない場合: 変更しない。 通常は 0 で使用して十分だと思います。startLBA が 0 の ときは、そのデータは IPL で読み込まれるべきデータと解 釈され、IPL サイズは上書きされますし、そうでない場合は 変更されないので便利です。ただし、RDRAM 上に用意したバッ ファ以上のサイズのデータを IPL ファイルとして使用した い場合は、自分で計算して指定するしかありません。計算は、 サイズを 19720 で割るだけで結構です(ゾーン 0 のため)。 *注 getdata を指定した場合は、writeSize ではなく totalSize か ら IPL サイズが計算されます。 getdata, totalSize, writeBuf, writeSize getdata が0かそうでないかによって意味がかわります。 通常は getdata を指定し、iplSize に0を指定して使用すると便利 です。 ○getdata が0のとき writeBuf で示されたアドレスから writeSize バイトをディ スクに書き込みます。RDRAM 上に確保できるバッファのサイ ズは限られているため、この方法では、大容量のデータをディ スクに書込みたい場合は ddWrite を何度も呼ぶ必要があり ます。 この時、 writeBuf: 書き込みたいデータをここで指定するアドレスに格納して ください。アドレスは必ず16バイト整列されたものを指定 してください。 writeSize: 何バイト書き込みたいかを指定します。ブロック丁度の数 にする必要はありません。ブロックに満たない部分は書き込 み時に 0xff で埋められます。 iplSize が0のときは、この値を用いて IPL サイズが計 算されます。 totalSize: 無視されます。 ○getdata が0でないとき getdata は関数へのポインタと解釈されます。関数の機能と しては、第一引数で示されたアドレスに第二引数で示された バイト数のデータを(他の大容量デバイスから)転送するもの です。getdata からの返り値は転送が正常に終了したかどう かを判断するために用いられます。0なら正常として続行、 0以外なら異常として処理を中断してその値を返り値として 終了します。writeBuf からの writeSize バイトはバッファ として利用されます。 ddwrite は (*getdata) を使用して、ディスクに書き込むべ きデータを writeBuf からのバッファに転送し、そのデータ をディスクに書き終えたら、再度 (*getdata) を使用して転 送し、ということを繰り返して、totalSize バイト書き込む、 というわけです。 この時、 writeBuf: バッファへのポインタです。ここからの領域にデータをい れておく必要はありません。16バイト整列が必要です。 writeSize: バッファのサイズを示します。用意されたバッファが1ブ ロック分に満たない場合はエラーが返ります。 このサイズを大きくとるほど、書き込みのパフォーマンスは 向上します。 totalSize: 書き込む総バイト数です。4の倍数にしてください。この 値がブロック丁度でない場合、残りの部分は 0xff で埋めら れます。iplSize が0のときは、この値を用いて IPL サイ ズが計算されます。 getdata: ddwrite が、他のデバイスから RDRAM にデータを転送す るために使用する関数です。この関数に例えば書き込みの途 中経過を表示する機能を入れることも可能です。正常に転送 できた場合は0を返すようにしてください。ddwrite から要 求される転送バイト数(第二引数)は必ず4の倍数です。また、 ddwrite は totalSize バイト以上の転送を要求することも ありません。 flags ………… 下記の意味を持ちます。 DDWRITE_FLG_FORMAT ディスクを強制的にフォーマットします。通常は、フォーマッ トされているかどうかは自動的に検知するのですが、何らか の理由で「フォーマットされていないのにフォーマットされ ているものと認識」した場合には、このフラグを立てて実行 するとディスクがうまく動作するようになります。 DDWRITE_FLG_IDSERIAL ID を idAddr に指定したとき、指定した ID のシリアル番 号(工場ライン番号と生産時刻)だけがディスクに書かれ、他 のメンバは変更されません。 formatHook …… ディスクがフォーマットされるときは、この関数がよばれます。 ツール側で、「ディスクをフォーマットしています。」等の表 示をするためのフック関数とお考え下さい。0 を指定するとフッ クされません。 infoHook ……… 実際にライトをする直前に、ツール側に disk type, load addr, ipl size の3つの情報を通知するためにフックされる 関数を指定します。この関数の引数は、DDInfo 構造体です。 この構造体については、ddGetInfo 関数の説明をお読み下さい。 通知された情報はこの関数からリターン後は失われますので、 必要があればツール側でバックアップをとるようにしてくださ い。0 を指定するとフックされません。 ○ID のフォーマットについてのまとめ ・変更したくないとき idAddr に0を指定する。 ・シリアル#(工場ライン番号と生産時刻)のみ変更したいとき idAddr からの 32バイトにディスク ID をいれ、 DDWRITE_FLG_IDSERIAL ビットを立てる。(idAddr からの 32 バイトのうち、シリアル#の部分だけがディスクに上書きさ れます。但し、ディスクの ID に何も書かれていなかった場 合は、シリアル#以外の部分は0になります。 ・全部変更したいとき idAddr からの 32バイトにディスク ID をいれる。 DDWRITE_FLG_IDSERIAL ビットは立てない。 ===================================================================== ・s32 ddGetInfo(DDInfo *info) ------------------------------------------------------------------ ディスクに書かれている情報を読み出し、info に格納します。どのような情 報が読み出されるかは、下記の DDInfo 構造体の説明を参照してください。 返り値は0が正常終了、0以外が異常終了です。異常終了として23が返って くる場合は、ディスクがまだフォーマットされていないと考えられます。その 他の値は 64DD の通常のエラーコードと同じです。必ず返り値はチェックして ください。異常終了の原因としては主にディスクが挿入されていない、等の (回復可能な)エラーが考えられます。 ===================================================================== DDInfo 構造体の説明 typedef struct{ s32 diskType; void *loadAddr; u32 iplSize; } DDInfo; diskType ……… ディスクタイプが読み出され、ここに格納されます。 loadAddr ……… ロードアドレスが読み出され、ここに格納されます。 iplSize ……… IPL サイズが読み出され、ここに格納されます。 ===================================================================== ・s32 ddUnformat(void *buffer, u32 bufSize); ------------------------------------------------------------------ ディスクを初期化します。この関数をよぶ際には、あらかじめ用意しておいた バッファのポインタとサイズを引数にいれてください。 初期化にかかる時間は、バッファを6Mバイト用意すると約2分半です。バッ ファのサイズをこれより小さくすると、より時間がかかります。 返り値は0が正常終了、0以外が異常終了です。返り値は 64DD の通常のエラー コードと同じです。必ず返り値はチェックしてください。異常終了の原因と しては主にディスクが挿入されていない、等の(回復可能な)エラーが考えられ ます。 ===================================================================== III. 使用例 ここでは、この関数を使用する際の使用例を示します。 ・イニシャライズについて PI マネージャは立ち上げておく必要がありますが、leo マネージャは立ち上 げる必要がありません。ddWrite, ddGetInfo 使用時に自動的に立ち上がりま す。但し、これらの関数を使用する前に他の通常の 64DD 関数を使用する場合 は、プログラマ側で立ち上げておいてください。 ・ddWrite の使い方 DDCmd command; command.startLBA = (書込み開始 LBA); command.diskType = (ディスクタイプ); command.loadAddr = (load address); command.idAddr = (ID 格納アドレス); command.flags = 0; if (ID をシリアル番号のみ書くとき) { command.flags |= DDWRITE_FLG_IDSERIAL; } command.iplSize = 0; command.writeBuf = (用意したバッファ); command.writeSize = (バッファのサイズ); command.getdata = (転送プログラム); command.totalSize = (書込み総バイト数); if (フォーマットをしなおすとき) command.flags |= DDWRITE_FLG_FORMAT; /* * write する */ error = ddWrite(&command); if (error) { /* エラーの発生をユーザに通知 */ } else { /* 書込みに成功したことをユーザに通知 */ } ・getdata 作成例 getdata の作成例です。この例では、hostio を使用して、まず何バイトデー タが必要かを Host に通知した後に、データを受け取っています。 エラーが発生する可能性があるデバイスからデータを転送する場合は、エラー のチェックもしてください。 s32 getdata(void *addr, u32 nbytes) { /* * hostio を使用して、要求されたデータを転送 */ osWriteHost((void *)&nbytes, sizeof(nbytes)); osReadHost(addr, nbytes); return 0; } IV. 使用条件(注意事項を含む) ○ID の設定について ID をユーザが書き換えようとしたときは、ユーザの指定した ID にシリアル 番号を下記のように上書きした上で、ddWrite に渡してください。決してユー ザが指定した ID をそのまま ddWrite に渡さないでください。 ID をユーザが書き換えようとしなかったときも、シリアル番号のみを上書き してください。これにより、同一 ID のディスクが氾濫することを防ぐことが できます。 シリアル番号(工場ライン番号と生産時刻) 工場ライン番号 ディスクを書込んだマシン名もしくはユーザ名を取 得して書込んでください。 生産時刻 現在時刻を取得して書込んでください。 もう一つの機能として、「ID を書き換えない」という機能をツールにつけて 下さい。 ○iplSize について ユーザに設定をさせるのではなく、ツール側で自動計算するか、0を指定して ライブラリに自動計算させるかのどちらかにしてください。 0を指定すると、startLBA が0のときに限ってサイズ(getdata を指定した場 合は totalSize, 指定しなかった場合は writeSize)から自動的に計算され上 書きされます。 getdata を指定した上で、iplSize に0を指定する使用方法をおすすめします。 ○startLBA, diskType, loadAddr について 有り得ない値(例えば、startLBA に 5000 とか、diskType に 10 といった値) を指定することもできますが、その結果できたディスクは当然動作しないもの になります(ddWrite が誤動作することも考えられます)。これらの値のチェッ クはツール側でお願いします。 ○未使用のディスクが挿入されることも考慮してください。 未使用のディスクに対して ddWrite(), ddGetInfo() 以外の関数を使用すると ハングアップします。 ******* ドキュメント変更履歴 -------------------- 97/12/01 * 最初のバージョン 98/01/09 ver.1.00 * ドキュメントの名称変更 * 構成を変更(最初のバージョンの内容は II章へ) * libddwrite.a は libleo_d.a を含んでいるという記述を追加 * ddwrite.h と leo.h のインクルードの順番に関する記述を追加 * DDCmd 構造体の、totalSize, getdata メンバの説明を追加 * DDCmd 構造体の flags に DDWRITE_FLG_IDSERIAL を追加 * ddGetInfo の返り値として23が返ってきた場合、ディスクがフォー マットされていないことが考えられるという記述を追加 * ddWrite, ddGetInfo ともに、返り値はエラーコードになっている、 という記述を追加 * ID のフォーマットについてのまとめを追加 98/02/21 ver.1.10 * DDCmd 構造体に、formatHook, infoHook を追加 * ddUnformat 関数を追加 98/04/21 ver.1.11 * ddWrite, ddGetInfo, ddUnformat 等の関数を呼んだ後に LeoLbaToByte などの関数を呼ぶと、ディスクタイプが0以外のディ スクの場合誤動作してしまうバグを修正(ドキュメントの変更はな し) 98/06/24 ver.1.12 * ひとたびエラーが起きたら、要因をクリアしてもエラーが出続ける バグを修正(ドキュメントの変更はなし) 98/06/29 ver.1.13 * 未フォーマットディスクへのID書き込みがエラーを起こしていた のを修正 * DDCmd 構造体の getdata が0でなく、かつwriteSize が一ブロッ クに満たない場合 DDWRITE_ERROR_INSUFFICIENT_BUFFERSIZE エラー を返すようにした。 * ddUnformat() に渡すバッファサイズが一ブロックに満たない場合 DDWRITE_ERROR_INSUFFICIENT_BUFFERSIZE エラーを返すようにした。 * _ddBfill() に渡すフィルサイズが四の倍数でない場合の端数処理 を追加した。
Name |
Last commit
|
History
|
Last Update |
---|---|---|
.. | ||
CVS | ||
dd64drv | ||
sample | ||
Makefile | ||
README | ||
ddwrite.h | ||
ddwriteint.h | ||
dodiskwrite.c | ||
dummyread.c | ||
formatdisk.c | ||
getinfo.c | ||
init.c | ||
libddwrite.a.uu | ||
libleo_sp.a | ||
locdefs | ||
setid.c | ||
system.c | ||
table.c | ||
unformat.c | ||
util.c | ||
write.c |