カーネルに仕込みを入れなくても"Illegal instruction trap"を捕まえる方法を考案しました。成功率は高くないかもしれませんが、うまくいった場合はHALT信号をトリガにすることができます。手順を以下に説明します。
1) カーネルを起動してシングルユーザーモードのシェルのプロンプトが出た状態にする
2) HALTスイッチを押してODTを起動する
3)以下のようにメモリ書き換え/レジスタ設定を実行する
@10/001724 400 // Illegal instruction trapベクタを400に変更
@20/001724 400 // IOT trapベクタを400に変更
@400/001724 0 // HALT命令に書き換え
@402/000356 0 // 念のためにもう一つHALT
@777100/177775 400 // breakpointを400に設定
@20/001724 400 // IOT trapベクタを400に変更
@400/001724 0 // HALT命令に書き換え
@402/000356 0 // 念のためにもう一つHALT
@777100/177775 400 // breakpointを400に設定
@p // シェルに復帰
4) シングルユーザモードのまま以下のコマンドを実行
# mount -a
# cd /usr/src/sys/GENERIC; make clean; make
うまくいけば"Illegal instruction trap"や"IOT trap"が発生した際にODTを起動し、breakpointによってHALT信号をアサートしてロジアナなどのトリガにすることができます。
成功して、ロジアナで取れたデータを解析したところ、やはり2.11BSDの場合と同様
正常な命令を読み込んだにもかかわらず"Illegal instruction trap"が発生した
ように見えるという現象が観測できました。
なお、再現実験を繰り返しているとファイルシステムが破壊される可能性が高いので、SDカードのイメージのバックアップを取っておくことをお勧めします。
補足説明
このような回りくどい方法を採用したのには理由があります。
DCJ11がトラップベクタの2 word(PC, SR)をアクセスする際は、「命令アクセス」ではなく、データとしてのメモリアクセスを行います。よって、命令アクセスを検出するブレークポイントでトラップベクタのアドレスを指定しても効果がありません。やむを得ず、トラップベクタのPCをアクセスされないはずのメモリ領域(アドレス400近傍)に書き換え、そこをブレークポイントで検出するようにしました。
0 件のコメント:
コメントを投稿