実行中にODTでメモリを書き換える方法は
- 操作が煩雑
- 問題の再現性が低い(気がする)、あるいは挙動が変化する
ため、 カーネルにバイナリパッチを当てて自力でトリガをかけられるようにしました。
ソースコードの変更ではなくバイナリパッチなのは、
インストールされるカーネルバイナリと一致するソースコードが見つからない
ためです。
後述するFPGAの変更と組み合わせることで、誤動作の発生を高確率で捕まえられるようになりました。
カーネルのバイナリパッチ
オリジナルのカーネル(rpunix)とパッチを当てたカーネルを比較すると以下のようになります。
41 324 202
42 3 4
49 324 202
50 3 4
1187 346 300
1188 35 25
1189 170 172
1190 373 377
1191 46 310
1192 20 25
1193 346 1
1194 35 0
1195 234 300
1196 133 25
1197 146 200
1198 20 376
1199 246 310
1200 20 25
1201 346 1
1202 20 0
1203 203 0
1204 35 0
先頭の4か所はトラップベクタの書き換えです。"Illegal instruction trap"と"IOT trap"の発生時に関数dzdmaにジャンプします。残りの部分は、使用されていないドライバの関数(002202 T dzdma)を上書きして、以下の命令列を書き込んでいます。アドレス依存性はないのでソースコードのアドレス指定は気にしなくても大丈夫です。
1 .asect
2 000400 .=400
3 000400 012700 177572 mov #177572,r0
4 000404 012710 000001 mov #1,(r0)
5 000410 012700 177200 mov #177200,r0
6 000414 012710 000001 mov #1,(r0)
7 000420 000000 halt
177572はMemory Management Register #0のアドレスです。"1"を書き込むことでアドレス変換を有効にしています。
177200はHALT信号をアサートするためのI/Oポートで、今回のデバッグのために追加しました。FPGAの変更については後述します。
FPGAの変更
I/Oポート(177200)に書き込みを行うとHALT信号をアサートするように改変しました。変更内容は以下のとおりです。
diff --git a/hdl/20251017/TangConsoleDCJ11MEM_project/src/top.v b/hdl/20251017/TangConsoleDCJ11MEM_project/src/top.v
index 4133bd9..e4a4380 100644
--- a/hdl/20251017/TangConsoleDCJ11MEM_project/src/top.v
+++ b/hdl/20251017/TangConsoleDCJ11MEM_project/src/top.v
@@ -2219,6 +2219,13 @@ module top(
default:;
endcase
+ always @(posedge sys_clk or negedge INIT_n)
+ if( ~INIT_n )
+ dbg_trg <= 1'b0;
+ else if(negedge_SCTL_n & bus_write && address == 18'o777200)
+ dbg_trg <= 1'b1;
+
+/* -----\/----- EXCLUDED -----\/-----
always @(posedge sys_clk or negedge RESET_n)
if( ~RESET_n )
{REG_DBG_CP, dbg_trg} <= 0;
@@ -2230,6 +2237,7 @@ module top(
REG_DBG_CP <= 1'b1;
else if( (address[15:0] == REG_DBG2) & aio_iread & REG_DBG_CP)
dbg_trg <= 1'b1;
+ -----/\----- EXCLUDED -----/\----- */
// else if( (address == 16'o001040) & aio_iread ) // trap at 'panic:'
// dbg_trg <= 1'b1;
// else if( (dpwa == (16'o25246 >> 1)) & (we0_lo | we0_hi |we1_lo | we1_hi))
オリジナルのデバッグ機能(ブレークポイント)と競合するので、該当部分をコメントアウトしています。
バッチの置き場所
パッチを当てたカーネルのバイナリと、FPGAのソースコードに対するパッチをここに置きました。ご利用ください。add-self-abort.patchとrpunix.patchedです。
(3月27日追記) 2.11BSDでも同様の解析ができるように、カーネルパッチを置きました。2.11BSDのカーネルパッチ FPGAは2.11BSD用のアドレス拡張版が必要です。FPGAのパッチ
0 件のコメント:
コメントを投稿