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