2026/04/17

TangConsoleDCJ11MEMにおける2BSDの誤動作の調査 その3

誤動作の原因の二つ目が判明しました。

符号なし2進数と符号付2進数の比較

後述するSOFUB_MAPの実装に符号なし2進数と符号付2進数を比較しているコードがありました。直接の比較ではありませんでしたが、符号なし整数の値を符号付整数の変数に代入し、その変数と定数を比較していたため、意図した通りには動作しない場合がありました。

問題発生のシナリオは以下の通りです。

  1. メモリ不足のためプロセスのテキスト領域(サイズ>=32768)のswap領域への書き出し処理が始まる
  2. buf構造体のb_bcountにサイズが格納されてsofub_alloc()に渡される
  3. sofub_alloc()では符号付整数のcountにb_bcountが代入される
  4. 関数の中でcountを正の定数と比較する(if文)
  5. countは負の値となるため条件が不成立となる(条件が成立した場合はテキスト領域のコピー処理が実行される)
  6. 5.で条件が不成立となった結果テキスト領域がコピーされずに過去にコピーされた別のデータがswap領域に書き込まれる
  7. 後にテキスト領域がswap領域から読み込まれるが、無関係のデータが復元されるためプログラムが誤動作する

2.11BSDのCプログラムのスタートアップコードはpure executable用とseparate executable用の二種類あるのですが、誤動作していたプログラムテキストの先頭部分はpure用ではなくseparate用に置き換わっていました。先頭以外の部分にも他のプログラムのヒープ領域と思しきデータがありました。

 SOFUB_MAPとは

UNIBUS用のデバイスはDMAアドレスが18bitなので、メインメモリのアドレスが18bitを越える領域に直接アクセスすることができません。このため、PDP-11ではUNIBUS用のMMUが実装されているのですが、TangConsoleDCJ11MEMにはDMA用のMMUはありません。

そこで登場するのがSOFUB_MAPです。18bitのDMAアドレスでアクセスできる範囲に中間バッファを設け、このバッファで中継することでメインメモリ全領域とのI/Oを実現しています。ISAバスのバスマスタデバイスで1MBを越えるメインメモリを扱う際の技法であるbounce bufferと同類です。

SOFUB_MAPではDMAの前後に必要に応じてメモリコピーを実行するのですが、上述のシナリオでこのコピー処理がスキップされた結果、バッファに残っていた別のデータがディスクに書き込まれていました。 

通常のファイルI/Oでは転送サイズが32KB以上になることはないので正常に動作していましたが、swapデバイスとのI/Oでは32KB以上になることがあるため、問題が発生していました。

修正内容

問題の原因がわかってしまえば修正は簡単で、変数countの型を符号なしにしました。修正パッチ 

なお、DMA完了時に呼ばれるsofub_relse()ではcountはunsignedで宣言されているので修正の必要はありませんでした。

2026/04/10

TangConsoleDCJ11MEMにおける2BSDの誤動作の調査 その2

問題の原因の一つが判明しました。

DCJ11が駆動する場合のABORT信号の扱いが仕様を満たしていないのがメモリ内容の上書きを発生させていました。

ABORT信号の扱い

ABORT信号は双方向の信号で、CPUが駆動する場合と外部回路が駆動する場合があります。CPUが駆動する場合の扱いについては、DCJ11 UG 3-6に以下のように規定されています。 

 If an internally generated abort condition such as an MMU error or address error exists, the DCJ1l asserts ABORT during the first part of the cycle. If this type of abort occurs, the DAL, BS, and MAP information should be ignored for the remainder of the cycle.

 オリジナルのFPGAの実装ではCPUが駆動しているABORT信号については関知していないため、以下のシナリオでメモリが破壊されていました。

  1. haltコマンドのテキスト領域とスタック領域が物理アドレス上で隣接する場所に割り当てられる。アドレスは昇順にテキスト、スタックと並んでいる。
  2. スタックポインタが減算される。減算されたポインタの物理アドレスは上記のテキスト領域を指している。
  3. 2.で減算されたポインタへの書き込み命令が実行されようとする 。書き込むデータは#4で命令コードとして解釈するとIOTとなる。
  4. MMUによりスタック領域の範囲外へのアクセスが検出され、バスへの書き込みサイクルがABORT信号の駆動によって無効化されるが、バスサイクルそのものは発生する。
  5. FPGAはABORT信号の入力を関知せず、書き込みサイクルを実行する。
  6. 5.の書き込みによって隣接するテキスト領域の命令が上書きされてIOT命令になる
  7. MMUによってトラップが発生し、スタック領域に別のメモリ領域が割り当てられて拡張される。
  8. 4.で中断された書き込み命令が再度実行される。 
  9. haltコマンドが6.のIOT命令を実行して異常終了する。

 FPGAのメモリへの書き込み処理を変更して、ABORT信号がアサートされている場合にバスサイクルを無視するように修正したところ、2.11BSDのhalt命令の誤動作と、2.9BSDのカーネルビルド時の誤動作については再現しなくなりました。

2026/03/25

2BSDの誤動作をバイナリパッチで捕まえる方法 その2

 実行中にODTでメモリを書き換える方法は

  1. 操作が煩雑
  2. 問題の再現性が低い(気がする)、あるいは挙動が変化する

ため、 カーネルにバイナリパッチを当てて自力でトリガをかけられるようにしました。

ソースコードの変更ではなくバイナリパッチなのは、

インストールされるカーネルバイナリと一致するソースコードが見つからない

ためです。 

後述する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のパッチ

2026/03/23

2BSDの誤動作をバイナリパッチで捕まえる方法 その1

 カーネルに仕込みを入れなくても"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に設定
@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近傍)に書き換え、そこをブレークポイントで検出するようにしました。

2026/03/21

TangConsoleDCJ11MEMにおける2BSDの誤動作の調査 その1

2.9BSDの誤動作

オリジナルのFPGAで2.9BSDの誤動作が確認できました。確実に再現します。

再現方法と実行結果

 シングルユーザモードで起動後、以下のように実行します。

# mount -a
Mounted /usr on /dev/rp1h
# cd /usr/src/sys/GENERIC; make clean; make
rm -f *.o *.i
cc -V -S -O -DKERNEL -I. -I/usr/include ../sys/sys2.c
ed - < :splfix.movb sys2.s
as -V - -o sys2.o sys2.s
rm sys2.s

(snip)

cc -V -S -O -DKERNEL -I. -I/usr/include ../dev/ttynew.c
ed - < :splfix.movb ttynew.s
as -V - -o ttynew.o ttynew.s
rm ttynew.s
cc -V -S -O -DKERNEL -I. -I/usr/include ../dev/tty.c
ed - < :splfix.movb tty.s
Illegal instruction - core dumped
# strings core | head
@q6N
core
core
make
h
 h
  .

R0
MAKE.  VERSION 2.58     14 MARCH 1979
=|^();&<>*?[]:$`'"\
 :;&>|
No description argument after -f flag

# adb /bin/make core
$R
ps      0170011
pc      034110
sp      0171272
r5      0171306
r4      0171370
r3      0
r2      0
r1      06
r0      01560
034110:         mov     sp,r5
# make
cc -V -S -O -DKERNEL -I. -I/usr/include ../dev/tty.c
ed - < :splfix.movb tty.s
as -V - -o tty.o tty.s
rm tty.s

カーネルをビルドするとmakeが異常終了します。

コアダンプを調べても実行した命令は正常です。また、続けてmakeを実行すると正常に動作するので、ファイル上にもメモリ上にも不正な命令は存在しないものと考えられます。

2.11BSDの誤動作

 改造版のFPGAとPCBで2.11BSDの誤動作を確実に再現できる方法が見つかりました。

 再現方法と実行結果

 シングルユーザモードで起動後、以下のように実行します。

 @773010
73Boot from rk(0,0,0) at 0177404
:
: rk(0,0,0)unix
Boot: bootdev=03000 bootcsr=0177404

2.11 BSD UNIX #32: Fri Mar 13 00:15:09 PST 2026
    root@:/usr/src/sys/SMALL


phys mem  = 655360
avail mem = 414912
user mem  = 307200

March 15 18:32:17 init: configure system

hk ? csr 177440 vector 210 skipped:  No autoconfig routines.
ht ? csr 172440 vector 224 skipped:  No autoconfig routines.
ra ? csr 172150 vector 154 skipped:  No autoconfig routines.
rl ? csr 174400 vector 160 skipped:  No autoconfig routines.
tm 0 csr 172520 vector 224 attached
tms ? csr 174500 vector 260 skipped:  No autoconfig routines.
ts ? csr 172520 vector 224 skipped:  No autoconfig routines.
xp ? csr 176700 vector 254 skipped:  No autoconfig routines.
erase, kill ^U, intr ^C
# halt
IOT trap - core dumped
# ls *.core
halt.core
# adb /sbin/halt halt.core
adb: no memory for symbols
adb> $r
ps      0170000
pc      041174
sp      0174510
r5      0175214
r4      0175262
r3      040312
r2      045
r1      0
r0      0144
041174:         add     $010,r4
adb> #
#

haltコマンドがIOT命令(000004)を実行して異常終了します。

ODTでメモリダンプを調べてみましたが、異常終了したプロセスの該当するPCの命令はファイル上の命令と一致していました。 

48chのロジックアナライザを接続してすべての信号を観測できる環境を作り、カーネルとFPGAに仕込みを入れてロジアナにトリガをかけてみましたが、バス上で観測された命令はファイル上の命令と一致しており、IOT命令ではありませんでした。

バスのトランザクションとしては以下のような流れでした。

  1. PC(041174)近傍の4命令が読み出される
  2. IOT trapのベクタの2 word(PC, SR)が読み出される
  3. IOT trapベクタに設定されているロジアナトリガ用の命令列が読み出される
  4. トリガ用のI/Oアドレスに書き込みが実行されてトリガ信号がアサートされる 

念のためにIOT命令を実行するテストプログラムを作成してロジアナで解析しましたが、こちらはきちんとIOT命令を読み込んでいることが確認できたので、解析方法に誤りはないと思います。 

考察

 以上の観測結果から考えて、どちらの誤動作も

メモリから読み出したものとは異なる命令を実行した

のが現象のように見えます。この仮説が正しいとして、原因が何かを考えてみたのですが、現時点では何も思いつきません。

(4月6日追記) IOT Trap発生時にカーネルスタックに保存されるPCは、IOT命令のアドレスではなく、+2した値のようなので、上記の解釈は誤りでした。-2したアドレスにはIOT命令が存在することが確認できました。

なお、以上の現象は2セットの個体を用いて検証しているので、ハードウェアの個体差やCPUの故障などは考えにくいと思われます。

(追記) "/.profile"を編集してPATHに2文字追加しただけで再現しなくなったりします。再現条件はかなり限定されるようです。

2026/03/15

【改訂版】TangConsoleDCJ11MEMへの2.11BSDのインストール

 

 TangConsoleDCJ11MEMに2.11BSDをインストールする方法を簡単に説明します。要点だけ書きますので、きちんとした手順書にはなっていません。ご承知おきください。

前提条件

Windows 11とLinux(WSL上で動作するUbuntu) での操作を前提に説明します。読者はそれぞれの環境でのコマンド実行などについては特に説明を要しないものとします。

環境構築

LinuxでSIMHとretro-fuseをインストールします。retro-fuseはソースからビルドします。

参照する情報

  1. 2.11BSDの文書 211bsd-setup.pdf
  2. SIMHに2.11BSDをインストールする手順 Installation of 2.11BSD on SIMH 
  3. retro-fuseの使い方 retro-fuse/wiki 

用意するもの

  1. 2.11BSDの配布ファイル 2.11BSD
  2. Pmod0に接続するmicroSDカードインタフェース Pmod MicroSD
  3. 2.11BSDのソースコードに適用するパッチ 「全部入り」のパッチ
(4月17日追記:カーネルのバグ修正のための追加パッチがあります 追加パッチ

 概略手順

  1. ハードウェアの改造とFPGAの更新
  2. SIMHをインストール
  3. SIMHに2.11BSDをインストール
  4. retro-fuseをインストール
  5. TangConsoleDCJ11MEMに2.11BSDをインストール
  6. インストールしたdiskイメージを書き換える

詳細手順

上記概略手順の1.、5.と6.についてはもう少し詳しく説明します。

TangConsoleDCJ11MEMの改造とFPGAの更新

FPGAについてはこちらのリポジトリの内容で更新してください。 更新すると下記の改造を施さない限り起動しなくなります。

メモリサイズを256KBから640KBに拡張するため、アドレス線の追加配線が必要です。

アドレス腺(DALH[18], [19])の接続方法ですが、パターンカットを行ってバススイッチを経由してレベル変換するやり方を紹介します。

パターンカットの場所

CPUソケットの表面内側でBS0, 1からのパターンをカットします。 配線の間隔が広いので難しくはないと思います。

ジャンパ配線

CPUのDAL18, 19をそれぞれU5(SN74CB3T3245DWR)の6,7ピンに接続します。また、J5のBS0,1をそれぞれPmod1のW19とF19にそれぞれ接続してください。

U5の足は細いですが、そもそもこの基板を実装できる方なら問題ないでしょう。 

テープイメージの作成

2.11BSDの配布ファイルがある場所で以下のコマンドでテープイメージを作成します。

#!/bin/sh

# file 0
dd if=mtboot    of=211bsd.img conv=notrunc
dd if=mtboot    of=211bsd.img conv=notrunc seek=1
dd if=boot      of=211bsd.img conv=notrunc seek=2
# file 1
dd if=disklabel of=211bsd.img conv=notrunc seek=65536
# file 2
dd if=mkfs      of=211bsd.img conv=notrunc seek=131072
# file 3
dd if=restor    of=211bsd.img conv=notrunc seek=196608
# file 4
dd if=icheck    of=211bsd.img conv=notrunc seek=262144
# file 5
dd if=root.dump of=211bsd.img conv=notrunc seek=327680
# file 6
dd if=file6.tar of=211bsd.img conv=notrunc seek=393216
# file 7
# (this file is intentionally unused)
# file 8
dd if=file7.tar of=211bsd.img conv=notrunc seek=524288
# file 9
dd if=file8.tar of=211bsd.img conv=notrunc seek=589824
# file 10
# (this file is intentionally unused)

ルートファイルシステムのインストール

テープから起動してルートファイルシステムをmkfs, restor, icheckします。

@100000g
100026
@0g
73Boot from tm(0,0,0) at 0172522
: tm(0,2)
Boot: bootdev=0402 bootcsr=0172522
Mkfs
file system: rk(0,0)
rk(0,0,0) disklabel missing/corrupt
file sys size [0]: 3072
bytes per inode [4096]: 
interleaving factor (m; 2 default): 
interleaving modulus (n; 100 default): 
isize = 768
m/n = 2 100
Exit called

73Boot from tm(0,0,2) at 0172522
: tm(0,3)
Boot: bootdev=0403 bootcsr=0172522
Restor
Tape? tm(0,5)
Disk? rk(0,0)
Last chance before scribbling on disk. End of tape    ### RETを入力
73Boot from tm(0,0,3) at 0172522
: tm(0,4)
Boot: bootdev=0404 bootcsr=0172522
Icheck
File: rk(0,0)
rk(0,0):
files 609 (r=208,d=22,b=144,c=230,l=5,s=0)
used 2738 (i=106,ii=0,iii=0,d=2632)
free 284
missing 0

73Boot from tm(0,0,4) at 0172522
: rk(0,0)unix
Boot: bootdev=03000 bootcsr=0177404

2.11 BSD UNIX #115: Sat Apr 22 19:07:25 PDT 2000
    sms1@curly.2bsd.com:/usr/src/sys/GENERIC

panic: iinit
no fs on dev 6/0
syncing disks... done

006102
@

オリジナルのカーネルではルートファイルシステムがマウントできないのでブートするとpanicします。 

 置き換えるファイルの作成

カスタマイズされたカーネルとRK05用のブートブロックを作成します。

  1. SIMHのディスクイメージをretro-fuseでマウント
  2. ソースコードにパッチを適用
  3. ディスクイメージをアンマウント
  4. SIMHを起動
  5. カーネルとブートブロックをビルド(SIMHで作業、手順は後述)
  6. SIMHを終了 
  7. SIMHのディスクイメージをretro-fuseでマウント
  8. ビルドしたカーネルとブートブロックをホストにコピー
  9. ディスクイメージをアンマウント

カーネルとブートブロックのビルド手順

カーネルとブートブロックのビルド手順は以下の通りです。

# cd /usr/src/sys/conf
# ./config SMALL
# cd ../SMALL
# make all
# cd ../mdec
# make

最初のmakeでカーネル(unix)が、次のmakeでブートブロック(rkuboot)が生成されます。 

次に、カスタマイズされたカーネルとブートブロックをmicroSDカードイメージに書き込みます。 
  • 2.11BSDがインストールされたmicroSDカードイメージを取得
microSDカード全体のイメージを取得します(rk05.img)
  • カードイメージ上のRK11のディスクイメージをretro-fuseでマウント
 $ bsd211fs -o fsoffset=512 -o mapuid=1000:0 -o mapgid=1000:20  rk05.img /tmp/bsd
  • カーネルをコピー
  • ディスクイメージをアンマウント
  • ブートブロックをディスクイメージに書き込む
$ dd if=rkuboot of=rk05.img seek=1024 conv=notrunc

ディスクイメージをmicroSDカードに書き戻せば準備完了です。 

/usrとソースコードのインストール手順

以後の作業はシングルユーザモードで行います。デバイスファイルを作成するだけでも分のオーダーの時間がかかるので、気長に待ちましょう。

なお、引数"br[012]"でデバイスを作成していますが、生成されるデバイスファイル名は"rp*"となります。MAKEDEVはこういう実装になっていますので混乱しないようにしてください。 

@3773010g
73Boot from rk(0,0,0) at 0177404
: rk(0,0)unix
Boot: bootdev=03000 bootcsr=0177404

2.11 BSD UNIX #32: Fri Mar 13 00:15:09 PST 2026
    root@:/usr/src/sys/SMALL


phys mem  = 655360
avail mem = 414912
user mem  = 307200

March 13 00:17:03 init: configure system

hk ? csr 177440 vector 210 skipped:  No autoconfig routines.
ht ? csr 172440 vector 224 skipped:  No autoconfig routines.
ra ? csr 172150 vector 154 skipped:  No autoconfig routines.
rl ? csr 174400 vector 160 skipped:  No autoconfig routines.
tm 0 csr 172520 vector 224 attached
tms ? csr 174500 vector 260 skipped:  No autoconfig routines.
ts ? csr 172520 vector 224 skipped:  No autoconfig routines.
xp ? csr 176700 vector 254 skipped:  No autoconfig routines.
erase, kill ^U, intr ^C
# cd /dev
# rm -f *rk* *mt* *rp*
# ./MAKEDEV rk0 tm0 br0 br1 br2 br3
# stty erase \^h
# stty crt
# rm -f swap drum
# mknod swap b 6 1
# mknod drum b 6 1
# ls -l rk0* *mt0 rp* swap drum
brw-r-----  1 root       6,   1 Mar 13 00:19 drum
brw-rw-rw-  1 root       1,   0 Mar 13 00:18 mt0
brw-rw-rw-  1 root       1,   4 Mar 13 00:18 nmt0
crw-rw-rw-  1 root       7,   4 Mar 13 00:18 nrmt0
brw-r-----  1 root       6,   0 Mar 13 00:18 rk0h
crw-rw-rw-  1 root       7,   0 Mar 13 00:18 rmt0
brw-r-----  1 root      11,   0 Mar 13 00:18 rp0a
brw-r-----  1 root      11,   1 Mar 13 00:18 rp0b
brw-r-----  1 root      11,   2 Mar 13 00:18 rp0c
brw-r-----  1 root      11,   3 Mar 13 00:18 rp0d
brw-r-----  1 root      11,   4 Mar 13 00:18 rp0e
brw-r-----  1 root      11,   5 Mar 13 00:18 rp0f
brw-r-----  1 root      11,   6 Mar 13 00:18 rp0g
brw-r-----  1 root      11,   7 Mar 13 00:18 rp0h
brw-r-----  1 root      11,   8 Mar 13 00:18 rp1a
brw-r-----  1 root      11,   9 Mar 13 00:18 rp1b
brw-r-----  1 root      11,  10 Mar 13 00:18 rp1c
brw-r-----  1 root      11,  11 Mar 13 00:18 rp1d
brw-r-----  1 root      11,  12 Mar 13 00:18 rp1e
brw-r-----  1 root      11,  13 Mar 13 00:18 rp1f
brw-r-----  1 root      11,  14 Mar 13 00:18 rp1g
brw-r-----  1 root      11,  15 Mar 13 00:18 rp1h
brw-r-----  1 root      11,  16 Mar 13 00:18 rp2a
brw-r-----  1 root      11,  17 Mar 13 00:18 rp2b
brw-r-----  1 root      11,  18 Mar 13 00:18 rp2c
brw-r-----  1 root      11,  19 Mar 13 00:18 rp2d
brw-r-----  1 root      11,  20 Mar 13 00:18 rp2e
brw-r-----  1 root      11,  21 Mar 13 00:18 rp2f
brw-r-----  1 root      11,  22 Mar 13 00:18 rp2g
brw-r-----  1 root      11,  23 Mar 13 00:18 rp2h
brw-r-----  1 root      11,  24 Mar 13 00:18 rp3a
brw-r-----  1 root      11,  25 Mar 13 00:18 rp3b
brw-r-----  1 root      11,  26 Mar 13 00:18 rp3c
brw-r-----  1 root      11,  27 Mar 13 00:18 rp3d
brw-r-----  1 root      11,  28 Mar 13 00:18 rp3e
brw-r-----  1 root      11,  29 Mar 13 00:18 rp3f
brw-r-----  1 root      11,  30 Mar 13 00:18 rp3g
brw-r-----  1 root      11,  31 Mar 13 00:18 rp3h
brw-r-----  1 root       6,   1 Mar 13 00:19 swap
# cd /
# mkfs -s 80000 /dev/rp0h40000 /dev/rp0h
isize = 10000
m/n = 2 100
# mkfs -s 40000 /dev/rp0h1h
isize = 10000
m/n = 2 100
# mkfs -s 10400 /dev/rp2a5200 /dev/rp2a 
isize = 1296
m/n = 2 100
# mkfs -s 32200 /dev/rp2c
isize = 8048
m/n = 2 100
# mount /dev/rp0h /usr
# mkdir /usr/src
# mount /dev/rp1h /usr/src
# mkdir /usr/src/ucb
# mount /dev/rp2a /usr/src/ucb
# mkdir /usr/src/sys
# mount /dev/rp2c /usr/src/sys
# df
Filesystem  1K-blocks     Used    Avail Capacity  Mounted on
root             3022     2706      316    90%    /
/dev/rp0h       39373        3    39370     0%    /usr
/dev/rp1h       39373        4    39369     0%    /usr/src
/dev/rp2a        5117        2     5115     0%    /usr/src/ucb
/dev/rp2c       31695        2    31693     0%    /usr/src/sys
# TAPE=/dev/nrmt0; export TAPE
# mt rew
# mt fsf 6
# cd /usr
# tar time tar xvb 20
x adm/README, 107 bytes, 1 tape blocks
x adm/daily, 1609 bytes, 4 tape blocks
x adm/lpd-errs, 0 bytes, 0 tape blocks

(snip)

ucb/page linked to ucb/more
ucb/uptime linked to ucb/w
ucb/u linked to ucb/users
ucb/reset linked to ucb/tset
     1015.1 real        34.8 user       980.2 sys  
# mt rew
# mt fsf 8
# cd /usr/src
# time tar xvb 20
x sys/pdpuba/tmscp.c, 55882 bytes, 110 tape blocks
x sys/pdpuba/rl.c, 18839 bytes, 37 tape blocks
x sys/pdpuba/tags symbolic link to ../sys/tags

(snip)

x include/utmp.h, 1125 bytes, 3 tape blocks
x include/varargs.h, 219 bytes, 1 tape blocks
x include/vfont.h, 546 bytes, 2 tape blocks
x include/Makefile, 2959 bytes, 6 tape blocks
      178.2 real         7.7 user       170.5 sys  
# mt rew
# mt fsf 9
# time tar xvb 20
x Makefile, 3536 bytes, 7 tape blocks
x asm.sed, 53 bytes, 1 tape blocks
x asm.sed.pdp, 53 bytes, 1 tape blocks

(snip)

x usr.sbin/ntp/patchl, 5658 bytes, 12 tape blocks
x usr.sbin/ntp/read_local.c, 655 bytes, 2 tape blocks
x usr.sbin/Makefile, 777 bytes, 2 tape blocks
     1373.0 real        56.8 user      1316.1 sys  
# df
Filesystem  1K-blocks     Used    Avail Capacity  Mounted on
root             3022     2706      316    90%    /
/dev/rp0h       39373    33417     5956    85%    /usr
/dev/rp1h       39373    37281     2092    95%    /usr/src
/dev/rp2a        5117     4126      991    81%    /usr/src/ucb
/dev/rp2c       31695     5180    26515    16%    /usr/src/sys
# TERM=vt100
# stty rows 56 cols 80 9600 crt
# mount /dev/rp0h /usr
# vi /etc/fstab

fstabを編集する(下記参照)

# umount /usr
# mount -a
# df
Filesystem  1K-blocks     Used    Avail Capacity  Mounted on
/dev/rk0h        3022     2706      316    90%    /
/dev/rp0h       39373    33417     5956    85%    /usr
/dev/rp1h       39373    37281     2092    95%    /usr/src
/dev/rp2a        5117     4126      991    81%    /usr/src/ucb
/dev/rp2c       31695     5180    26515    16%    /usr/src/sys
# cat /etc/fstab
/dev/rk0h       /               ufs     rw      1       1
/dev/rk1h       none            swap    sw      0       0
/dev/rp0h       /usr            ufs     rw      2       1
/dev/rp1h       /usr/src        ufs     rw      3       1
/dev/rp2a       /usr/src/ucb    ufs     rw      4       1
/dev/rp2c       /usr/src/sys    ufs     rw      4       1
# umount -a
# time fsck -y
** /dev/rk0h
File System: /

** Last Mounted on /
** Root file system
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Free List
590 files, 2706 used, 316 free
** /dev/rrp0h
File System: /usr

** Last Mounted on /usr
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Free List
4145 files, 33417 used, 5956 free
** /dev/rrp1h
File System: /usr/src

** Last Mounted on /usr/src
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Free List
6787 files, 37281 used, 2092 free
** /dev/rrp2a
File System: /usr/src/uc

** Last Mounted on /usr/src/uc
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Free List
584 files, 4126 used, 991 free
** /dev/rrp2c
File System: /usr/src/sy

** Last Mounted on /usr/src/sy
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Free List
931 files, 5180 used, 26515 free
      156.2 real        53.1 user       103.0 sys  
# halt
syncing disks... done
halting

000014
@3773010g
73Boot from rk(0,0,0) at 0177404

: rk(0,0,0)unix    ### ここはRETでもOK
Boot: bootdev=03000 bootcsr=0177404

2.11 BSD UNIX #32: Fri Mar 13 00:15:09 PST 2026
    root@:/usr/src/sys/SMALL


phys mem  = 655360
avail mem = 414912
user mem  = 307200

March 13 01:46:38 init: configure system

hk ? csr 177440 vector 210 skipped:  No autoconfig routines.
ht ? csr 172440 vector 224 skipped:  No autoconfig routines.
ra ? csr 172150 vector 154 skipped:  No autoconfig routines.
rl ? csr 174400 vector 160 skipped:  No autoconfig routines.
tm 0 csr 172520 vector 224 attached
tms ? csr 174500 vector 260 skipped:  No autoconfig routines.
ts ? csr 172520 vector 224 skipped:  No autoconfig routines.
xp ? csr 176700 vector 254 skipped:  No autoconfig routines.
erase, kill ^U, intr ^C
# ^DFast boot ... skipping disk checks
checking quotas: done.
Assuming non-networking system ...
checking for core dump... 
preserving editor files
clearing /tmp
standard daemons: update cron accounting.
starting lpd
starting local daemons: sendmail.
Fri Mar 13 01:47:26 PST 2026


2.11 BSD UNIX (curly.2bsd.com) (console)

login: root
erase, kill ^U, intr ^C
# cd /usr/games
# ls
adventure    btlgammon    hack         number       snake        worm
arithmetic   canfield     hangman      phantasia    snscore      worms
backgammon   cfscores     hunt         ppt          teachgammon  wump
banner       chess        lib          primes       trek         zork
battlestar   cribbage     mille        quiz         ttt
bcd          factor       monop        rain         wargames
bj           fish         moo          robots       warp
boggle       fortune      morse        sail         words
# ./zork
>                       Saves game on file dsave.dat
<                       Restores game from file dsave.dat
!command                Execute shell command from Dungeon


Welcome to Dungeon.             This version created 10-SEP-78.
You are in an open field west of a big white house with a boarded
front door.
There is a small mailbox here.
>look
You are in an open field west of a big white house with a boarded
front door.
There is a small mailbox here.
>open mailbox
Opening the mailbox reveals:
  A leaflet.
>get leaflet
Taken.
>read it
                    Welcome to Dungeon!
 
   Dungeon is a game of adventure, danger, and low cunning.  In it
you will explore some of the most amazing territory ever seen by mortal
man.  Hardened adventurers have run screaming from the terrors contained
within.
 
   In Dungeon, the intrepid explorer delves into the forgotten secrets
of a lost labyrinth deep in the bowels of the earth, searching for
vast treasures long hidden from prying eyes, treasures guarded by
fearsome monsters and diabolical traps!
 
   No DECsystem should be without one!
 
   Dungeon was created at the Programming Technology Division of the MIT
Laboratory for Computer Science by Tim Anderson, Marc Blank, Bruce
Daniels, and Dave Lebling.  It was inspired by the Adventure game of
Crowther and Woods, and the Dungeons and Dragons game of Gygax
and Arneson.  The original version was written in MDL (alias MUDDLE).
The current version was translated from MDL into FORTRAN IV by
a somewhat paranoid DEC engineer who prefers to remain anonymous.
 
   On-line information may be obtained with the commands HELP and INFO.
>quit
Your score would be   0 [total of 560 points], in    7 moves.
This gives you the rank of beginner.
Do you wish to leave the game?
y

# halt
syncing disks... done
halting

000014
@

以上でフルインストールとマルチユーザモードの起動確認の完了です。

設定変更

/etc/rcや/etc/rc.local、/etc/netstartは動作しないデーモンなどをコメントアウトするとよいでしょう。現時点で判明しているのは、lpd, hostid, sendmailです。

諸注意

RAMの拡張に伴い、ディスクのブートローダのアドレスが0773xxxから3773xxxに変更されています。 

動作が不安定で再現性のない挙動をします。例えば、カーネルをビルドするためにmakeを実行すると、makeが"Memory fault - core dumped"になったり、/lib/cppが"Fatal error in /lib/cpp"になったりします。

こんな状態なので、これはあくまでも「実験」です。 

(4月17日追記) FPGAの実装の修正(CPUが駆動するABORT信号の対応)とカーネルのバグ修正(追加パッチ)により不安定な動作は解消されました。カーネルのビルドを10時間以上繰り返しても問題ない程度に安定して動作しています。

2026/03/08

【続】TangConsoleDCJ11MEMへの2.11BSDのインストール ~アドレス腺の拡張方法~

アドレス腺(DALH[18], [19])の接続方法ですが、パターンカットを行ってバススイッチを経由してレベル変換するやり方を紹介します。

パターンカットの場所

CPUソケットの表面内側でBS0, 1からのパターンをカットします。 配線の間隔が広いので難しくはないと思います。

ジャンパ配線

CPUのDAL18, 19をそれぞれU5(SN74CB3T3245DWR)の6,7ピンに接続します。また、J5のBS0,1をそれぞれPmod1のW19とF19にそれぞれ接続してください。

U5の足は細いですが、そもそもこの基板を実装できる方なら問題ないでしょう。

TangConsoleDCJ11MEMにおける2BSDの誤動作の調査 その3

誤動作の原因の二つ目が判明しました。 符号なし2進数と符号付2進数の比較 後述するSOFUB_MAPの実装に符号なし2進数と符号付2進数を比較しているコードがありました。直接の比較ではありませんでしたが、符号なし整数の値を符号付整数の変数に代入し、その変数と定数を比較していたため...