dd error on unix/v6

女房が家のすぐ近くに無人野菜売り場を見つけた。探していて見つけた訳ではなく、車で 出かけた時、いつも通っている道に大型車が駐車してて脇を通るのが怖かったので、よそ道に 入ったとの事。そこで偶然に見つけたらしい。ナスとか有ったそうな。

翌日、トランシーバーとショ(商品)袋と小銭を持って、偵察兼仕入れに行かされましたよ。棲家から 直線にしてほんの100mぐらい。長年住んでるけど、こんなのが有ったとは、露知らず。 現着して入荷状況を女房に報告。こぶりなかぼちゃ、1個100円。みょうが1袋100円。ミニトマト 1袋100円、ナス1袋100円、とうがん1個100円、唐もろこし1本100円、大豆1袋200円。

ナスと唐もろこしの査収指示が出たので、貯金箱にお金を入れてから物を回収。もろこし、 甘くておいしかったよ。また、行ってみよう。

そうそう、おいらのトランシーバーにこの間、メールが着信した。読もうと思ってボタンを 押すも、メーラーが開けませんだってさ。Javaのディスパッチャーが壊れたかな。こんなの 初めての経験。 shutdown -r now なんていう機能は当たり前だけど搭載されていないので、 shutdown -p nowしてから、bootしたよ。boot時間の長い事、いらいらさせられるな。

いらいらと言えば、グリーとモバゲーのCM、しつこすぎてうざいな。たいして新規性もない くせにCM打ってる。裏で糸を引く、キャリアーも儲けたくて必死だな。

dd error

# dd if=/dev/mt0 of=fromBSD
Invalid magtape record length, PC: 021712 (RTS PC)
sim>

前回ddを使ってFreeBSDからunix/v6側にデータを持ってこようとしたら、上記のような エラーになってしまっていた。エラーの出方からして、unix/v6が出しているエラーとは考えにくい。 念の為、dd.cやkernの下やdmrの下を検索してみたけど、該当は無かった。

じゃ、エラーを出しているのは、simhの方だよな。検索したら、scp.cにエラーも文字列が 定義されてた。そして、それを、fprint_stopped()内で使ってる。やらしい事に、エラー文字列の 配列参照なんだけど。

run_cmd() {
   :
   r = sim_instr();
   fprint_stopped (stdout, r);
}

で、sim_instr()は PDP11/pdp11_cpu.c にあるシュミレータだ。ミニコンの動きをシュミレート 出来ちゃうのは面白いな。嗚呼、ソースを追うのしんどいな。globalするか。それともgdbするか? それが問題だ。取り合えず、直接的にgdbだな。(前から、こればっかり)

(gdb) b scp.c:2662
Breakpoint 1 at 0x809087e: file scp.c, line 2662.
(gdb) run uv6
Starting program: /usr/home/sakae/UV6/pdp11 uv6

PDP-11 simulator V3.8-1
Disabling XQ
@unix

login: root
# dd if=/dev/mt0 of=fromBSD
Breakpoint 1, run_cmd (flag=4, cptr=0xbfbfd4ec "") at scp.c:2662
2662    fprint_stopped (stdout, r);                             /* print msg */
(gdb) p r
$1 = 102
(gdb) bt
#0  run_cmd (flag=4, cptr=0xbfbfd4ec "") at scp.c:2662
#1  0x0808b687 in do_cmd (flag=1, fcptr=0xbfbfe254 "uv6") at scp.c:904
#2  0x0808ad91 in main (argc=2, argv=0xbfbfe730) at scp.c:660
(gdb) c
Continuing.

Invalid magtape record length, PC: 021712 (RTS PC)
sim>

よっしゃ、エラー番号が分かったぞ。(そんなのソース読んで、計算しろって?)

(gdb) b pdp11_cpu.c:722 if reason == 102
Breakpoint 1 at 0x804cb15: file PDP11/pdp11_cpu.c, line 722.
(gdb) b pdp11_cpu.c:2103 if reason == 102
Breakpoint 2 at 0x8051813: file PDP11/pdp11_cpu.c, line 2103.
(gdb) run uv6
Starting program: /usr/home/sakae/UV6/pdp11 uv6

PDP-11 simulator V3.8-1
Disabling XQ
@unix

login: root
# dd if=/dev/mt0 of=fromBSD
Breakpoint 2, sim_instr () at PDP11/pdp11_cpu.c:2103
2103    return reason;

勘でBP設定したけど外れか。止まった所は、sim_instr()の出口の所なんだよな。その間に いろいろな箇所で、reason変数に代入してる。はてどこだろう? 根気欲、潰していくしかないのかな。 何か旨い手はないものか。

もっと大局的に

旨い手を思いつかないので(根気のない、ヘタレですから)、もっと大局的に考えてみる。 今回unix/v6側に持ってこようとしたのは、FreeBSD側のテキスト。simhもからんでいるって事は、simh のフォーマットになってないかい? ありそうな予感。

unix/v6からBSDに輸出したものをそのまま輸入したらどうだろうか。これなら、間で変な加工を してても旨く行きそうだな。やってみるか。昔、MySQLだったかで、文字列を格納して、それを を読み出すと一部で文字化けがあった。途中にEUCとUNICODEの変換機が入っていて、それが 悪さしてた。なんて言うのが有ったからな。

# dd if=CATLOG of=/dev/mt0
48+1 records in
48+1 records out
# dd if=/dev/mt0 of=IMPORT
read: I/O error
49+0 records in
49+0 records out
# dd if=IMPORT of=/dev/mt0
49+0 records in
49+0 records out
# dd if=/dev/mt0 of=HOGE
read: I/O error
49+0 records in
49+0 records out
# cmp HOGE IMPORT
#

エラーになったけど、最悪の事態は免れたたな。書き出す時に、512byte単位にトレーラが 付くはずだから、FreeBSD側では、512x49になってるはず。

-rw-r--r--  1 sakae  kuma  25484  7 27 16:53 dump.tap
[sakae@cdr ~/UV6]$ echo '49*512' | bc
25088

サイズが合わないと言う事は。。。

[sakae@cdr ~/UV6]$ hd dump.tap | lv
00000000  00 02 00 00 2f 0a 2f 75  6e 69 78 0a 2f 72 6b 75  |...././unix./rku|
  :
00000200  6c 6e 0a 2f 00 02 00 00  00 02 00 00 62 69 6e 2f  |ln./........bin/|
  :
00000400  69 6e 0a 2f 75 73 72 2f  62 69 6e 2f 00 02 00 00  |in./usr/bin/....|
00000410  00 02 00 00 61 63 0a 2f  75 73 72 2f 62 69 6e 2f  |....ac./usr/bin/|
  :
00006280  41 54 4c 4f 47 0a 00 00  00 00 00 00 00 00 00 00  |ATLOG...........|
00006290  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00006380  00 00 00 00 00 02 00 00  00 00 00 00              |............|

ちょっと見にくいけど、512byte毎に、00020000を入れてるみたいだ。最後の部分は、00でpadding してるんかな。ちがうかな。最後の最後は0000が終わりマークとして入るのか。

で、謎の00020000なんだけど、今ふと思った所によると、512じゃん。(ああ、こういう事が 出てくるなんて、真性のバイナリアンじゃな)

sim> show tm0
TM0, attached to dump.tap, write enabled, SIMH format, unlimited capacity

で、上のSIMH formatっつうのを軽く調べてみたんだが、出てなかった。結局ソース嫁だな。 読んでたら日が暮れるので先へ進もう。いろいろと調べてみると、512のヘッダー/フッターを 差し込むプログラムを公開されてる方がおられた。

#! /usr/local/bin/perl
while(read(STDIN, $str, 512) > 0){
    print "\000\002\000\000";
    print $str;
    print "\000\002\000\000";
}
print "\000\000\000\000";
print "\000\000\000\000";

これを使えばSIMH用のテープを簡単に作れるよね。後はtarに変わる(アーカイバ)ものがないかだな。30秒 軽く考えて、昔sharなんてのが有った事を思い出した。sysの中にkernelのソースが一式 入っているとして

[sakae@cdr ~/UV6/sys]$ ls
buf.h           file.h          ken/            run             tty.h
conf/           filsys.h        param.h         seg.h           user.h
conf.h          ino.h           proc.h          systm.h
dmr/            inode.h         reg.h           text.h
[sakae@cdr ~/UV6/sys]$ shar `find . -print` | ../tar2tap.pl > ../dump.tap

sharを動かして、その結果にヘッダー/フッターを挟んで、テープを作るとな。

 :
mkdir -p ./conf > /dev/null 2>&1
echo x - ./conf/.listing
sed 's/^X//' >./conf/.listing << 'f826a136bc848f4754295984726fdc28'
Xtotal 46
Xdrwxr-xr-x  2 ftp  ftp    512 Jul 18  1975 .
Xdrwxr-xr-x  5 ftp  ftp    512 Jun 22  1975 ..
X-rw-r--r--  1 ftp  ftp     70 Jul 18  1975 data.s
X-rw-r--r--  1 ftp  ftp   9973 Jul 18  1975 m40.s
X-rw-r--r--  1 ftp  ftp  10479 Jul 18  1975 m45.s
X-rw-r--r--  1 ftp  ftp   8726 Jul 18  1975 mkconf.c
X-rwxr-xr-x  1 ftp  ftp   3258 Jul 18  1975 sysfix
X-rw^@^B^@^@^@^B^@^@-r--r--  1 ftp  ftp   2387 Jul 18  1975 sysfix.c
f826a136bc848f4754295984726fdc28
echo x - ./conf/data.s
sed 's/^X//' >./conf/data.s << 'a71e3bb3de150fc4ed2fc92ff6439431'
X/ l45.o needs to be in data space
X/ to get l45.o; as data.s l.s
X.data
a71e3bb3de150fc4ed2fc92ff6439431
echo x - ./conf/m40.s
 :

出来上がったテープの出来栄えを確認してみた。unix/v6って、残念ながらsedは入っていない。 よってこのテープを持って行っても役にたたんな。残念であります。後は、edを使って地道に 分解するしかないかな。嗚呼、めんどくせーーーーーー。

sharの代わりに超簡単なやつを書いてみた。

[sakae@cdr ~/UV6]$ cat mktap.sh
#!/bin/sh
for f in `find . -type f`
do
    echo '/* =====' $f ' */'
    cat $f
done

こやつを使って

[sakae@cdr ~/UV6/sys]$ ../mktap.sh | ../tar2tap.pl > ../dump.tap

unix/v6を起動して、ddでテープ内容を取り込み、edを使って(手動で)ファイルに切り刻んで いく。単純作業なので、暇な時にどうぞ。そうそう、edでは、余り大きなファイルは編集出来ないようで、ファイルの 尻尾が切れてしまいますので注意。

1,2p
/* ===== ./fio.c  */
#
/=====/
/* ===== ./iget.c  */
1,.-1w fio.c
4239
1,.-1d
1,2p
/* ===== ./iget.c  */
#

こんな具合にファイルを分割。最初にファイル名を確認。次のヘッダーまで移動。1行目から、 ポインターの前まで、名前を付けて保存。そして、今書き出した部分を削除。これを、ファイルの 最後まで繰り返し。はい、馬鹿がやる事です。ハッカーならそんな事は、コンピューターに やらせる事だよ、と突っ込みが入るに違いありません。

さくっと、v6root.gzを見つけてきました。 こやつからは起動出来ませんが、sys以下がそのまま保存されている所に価値があります。 展開して、root.dskとでも名前を付けてあげて、att rk4 root.dskでsimhに認識させた上で unix/v6を起動。後は、rk4を適当な所にmountしてから、カーネルのコンパイルに挑戦です。 runは、rkunixを作った所で終了するようにしておきます。また、runの中では、chdirコマンドが 使われていますが、以前勢いでshの内蔵コマンドをcdに変更しちゃったので、ちょいと 元に戻しておきました。

                if(equal(cp1, "chdir") || equal(cp1, "cd")) {

コンパイル時間を計りつつ、カーネルを作ってみます。

# time sh run
alloc.c:
clock.c:
  :
vs.c:
vt.c:
a.out /rkunix differ: char 2, line 1

real       50.0
user       32.7
sys        13.9

# cd conf
# ls -ltr
total 167
-rw-rw-r--  1 bin        70 Jul 17  1975 data.s
-rw-rw-r--  1 bin      2387 Jul 17  1975 sysfix.c
-rw-rw-r--  1 bin      8726 Jul 18  1975 mkconf.c
-rwxrwxrwx  1 root     3258 Jul 18  1975 sysfix
-rw-rw-r--  1 bin      9973 Jul 18  1975 m40.s
-rw-rw-r--  1 bin     10479 Jul 18  1975 m45.s
-rw-rw-rw-  1 root     4752 Aug 20 12:29 m40.o
-rw-rw-rw-  1 root     1517 Aug 20 12:29 c.c
-rw-rw-rw-  1 root      824 Aug 20 12:29 c.o
-rw-rw-rw-  1 root     1053 Aug 20 12:29 l.s
-rwxrwxrwx  1 root     7392 Aug 20 12:29 mkconf
-rwxrwxrwx  1 root    28636 Aug 20 12:29 a.out
# cp a.out /myunix

出来上がったものを、名前を付けて保存、そして再起動。

[sakae@cdr ~/UV6]$ pdp11 uv6

PDP-11 simulator V3.8-1
Disabling XQ
@myunix

login: root
#

ちゃんと起動しました。パチパチパチ。そして勢い余って、buildworldです。

 :
real     1:11.0
user       47.9
sys        19.4
s2
11: Missing file /usr/sys/ino.h
12: Missing file /usr/sys/filsys.h
8: Missing file /usr/sys/param.h
9: Missing file /usr/sys/proc.h
10: Missing file /usr/sys/tty.h
11: Missing file /usr/sys/user.h
15: Missing file /usr/sys/ino.h
16: Missing file /usr/sys/filsys.h
Can't create new file.

Simulation stopped, PC: 053446 (JMP 3602)

途中でdiskが壊れたみたいで、永久ループに入ってしまいました。DECの製品には今も昔も 泣かされますねえ。(RA81だかRA82というDiksのせいで、何回徹夜させられたか。。。) そんな事より、昔は、/usr/includeなんて無くて、直接カーネルのヘッダーファイルを 参照してたのね。(sysを変な所にマウントしてるんで、見えないんですが。)

Change df とか

この一連の記事で、初回にdfをやった時に訳の分からんデバイスを表示してエラーに なってた。ソースを調べてみたら、dfの対象デバイスがハードコートされてた。気分が 悪いので、修正しておいた。これ、きっと健さんからの練習問題に違いない。

# ed /usr/source/s1/df.c
1,9p
char    *dargv[]
{
        0,
        "/dev/rk0",
        "/dev/rk1",
        "/dev/rk2",
        "/dev/rk3",
        0
};

どうやら、答えは合ってたよ。KとRのあの本は、もう卒業しても宜しいでしょうか?

# df
/dev/rk0 2619
/dev/rk1 3697
/dev/rk2 1792
/dev/rk3 2549

diskがらみのコマンドが出てきたついでに、昔のものを一席。 fsckの始祖だそうです。エラーが出た時は、-sオプションを付けて補修するのだそうです。

# icheck /dev/rk4
/dev/rk4:
spcl       4
files    296
large     97
direc     24
indir     97
used    2972
free     941