NetBSD/i386のMBRのソースを読んでみることにしました。もしかすると起動しない原因が分かるかもしれません。まずNetBSDのcvswebで公開されているmbr.Sを入手します。FreeBSD/i386のmbrに比べると、条件アセンブルの指定が多いのでロジックを追いかけるときに注意する必要がありそうです。
ソースを読む時の心構えというほどのことでもありませんが、動作している状況を意識してからロジックを追うようにした方が早く内容を理解できると思います。これまでMBRの動作を見ている限りでは、次のようなロジックになっていると想像できます。
- パーティション選択メニューを表示する
- キー入力を待つ
- 選択されたパーティションのPBRに制御を移す
/*入力されたスキャンコードを変換してBDA(BIOS Data Area)の0x0475の値と比較しています。何故このロジックが必要なのか不明ですが、比較結果に問題がなければラベルboot_ptnに飛び、(何かが?)問題ならラベルboot_lbaかread_chsに制御が移るようです。
* We have a keycode, see what it means.
* If we don't know we generate error '?' and go ask again
*/
check_key:
/*
* F1-F10 -> boot disk 0-9. Check if the requested disk isn't above
* the number of disks actually in the system as stored in 0:0475 by
* the BIOS.
* If we trust loc 475, we needn't check the upper bound on the keystroke
* This is always sector 0, so always read using chs.
*/
subb $KEY_DISK1, %al
cmpb 0x0475, %al
jae boot_ptn
addb $0x80, %al
pop %dx /* dump saved drive # */
push %ax /* replace with new */
#ifdef NO_CHS
xorl %ebp, %ebp /* read sector number 0 */
jmp boot_lba
#else
movw $chs_zero, %si /* chs read sector zero info */
jmp read_chs
#endif
ここはNO_CHSの定義で条件アセンブルされていますが、どうもNO_CHSは未定義のようなのでラベルread_chsの方が使われているようです。これは従来のCHS形式でINT 13Hを呼び出すので「8GBの壁」問題を起こす可能性がありそうです。これはセクタ0を読んで制御を移す処理のようなので、PCの観察者からするとパーティション選択メニューが再表示されるように見えます。これは僕が体験したエラー情況と整合します。つまり問題はjae boot_ptnで分岐しなかったことにあると考えられます。いったい0x0475に格納されている値が何だったのか知りたいところですが、デバッグ環境が無いのでこれ以上の調査はできません。
あまり推奨できる方法ではありませんが、バイナリエディタHxDを使ってjae boot_ptnをjmp boot_ptnに変更するパッチをあてて対処しようと思います。i386は条件分岐命令jaeが0x73で無条件分岐命令が0xEBなので、該当アドレスが見つかれば対応できます。NetBSD/i386の環境があればスマートに作業できると思うのですが、あまり環境が整っていないので泥臭い方法で対処しました。
HxDでセクタ0の16進ダンプを見ながらmbr.Sを参照しつつハンド逆アセンブルして該当アドレスを見つけました。アドレスが分かれば変更するのは1バイトだけなので、すぐに出来ます。こういう荒業は何が起きるか分からないので注意に注意を重ねて実行しなければなりません。今回はUSB-HDDが潰れても別に構わないので、多少心理的負担は少なくてすみました。
いよいよパッチをあてたUSB-HDDをdynabook SS SX/15Aに接続して電源を入れてみます。今度こそ上手くいって欲しいものです。ここしばらくは、上手くいって欲しいと願いながら電源を入れて、エラーがでたりすることが多かったので、だんだん疲れてきました。
0 件のコメント:
コメントを投稿