netbsd(2)

ある朝、田園地帯を散歩していると、ドンと音がしました。花火とは違うみたいだなあと、 いぶかしげに音がした方向を見ると、10mぐらいのポールをするすると、鳥様なものが落ちて いきます。

ははは、始まったな、季節の風物視、鳥追い払い用の、ドッカンと音がする装置が設置 されたようです。朝の遅い人には、迷惑至極みたいですけど、美食家の鳥さんも、おいしい 果物に近づけずに困っておられるでしょう。

いままで、このドッカン装置がどうなっているか見た事無かったので、ポールを頼りに、 指で耳を塞ぎながら行ってみた。

3本のステーで、10mぐらいなポールが立っていたよ。根元は、消火器みたいのに繋がって いて、その上に、鳥の模型が鎮座してた。消火器みたいなやつから、高圧電気ケーブルらしき やつが出ていて、隣のビニールシートで覆われた部分に行っていた。

ビニールを捲くれば、仕掛けの全容が分かるだろうけど、既に果樹園に不法侵入しちゃってるか ら、それは諦め見るだけにした。その代わり、消火器みたいなやつに書いてあった、ドンピカ とタイガーって文字だけを、しっかり頭に記憶。記憶がこぼれ落ちないないように、そろそろと家に 帰ってきましたよ。

ぐぐる様に、2つのキーワードを入力しようとしたら、ぐぐる様が先回りしてこれでっしゃろ と教えてくれた。そして導かれるままに、バードキラー へと行き着いたよ。コンシェルジェだのう。アプルとかドコモが無くたって兵器だね。

ドンピカって、空港でも使われてんのか。飛行機のエンジンに鳥さんが飛び込んだら(バードストライク)、みんな 丸焼けになっちゃって大変だからね。

こういう音で撃退ってやついろいろあるよね。昔、どこかの公園で悪さをするアホウを 追い払う為、モスキート音を出す装置を設置したなんてニュースが流れてたけど、今夏は どうなんだろう?

in kernel

前回は、ユーザーランド側でのsyscallを見た。今度は、こちら側って言うかカーネル内の 動きでも見るか。例は、gettimeofday。pmaxなマシンでも、マイクロ秒単位のEPOCが得られるか 興味あったから。それと、gettimeofdayは、readとかと違って(非常に)ユニークだから、 コードを追うには最適だと思ったんだ。

#include <stdio.h>
#include <sys/time.h>

double u_clock()
{
    struct timeval tv;

   gettimeofday(&tv, NULL);
   return tv.tv_sec + tv.tv_usec * 1e-6;
}

main(){
  printf("%.6f\n", u_clock());
}

これ、前にSchemeの移植した時に造ったのの使い回しです。こういうのもオブジェクト嗜好って 言うんですかね?

pmax$ ./a.out
1279839718.347656
pmax$ ./a.out
1279839878.281250

一応、それらしく動いています。そんじゃ、カーネル側で、止めるべき所をnetbsd.mapから見繕って みます。

[sakae@secd ~/pmax/src/sys]$ grep gettimeofday netbsd.map
                0x00000000801d3ba0                sys_gettimeofday
sys_gettimeofday                                  kern_time.o

定義されてる所も表示してくれるので、とっても便利。

GXemul> br add 0x00000000801d3ba0
  0: 0x801d3ba0 (0x00000000801d3ba0)
GXemul> c

pmax$ ./a.out
801d3ba0: 27bdffd0      addiu   sp,sp,-48
BREAKPOINT: pc = 0x801d3ba0
(The instruction has not yet executed.)
GXemul> unassemble
801d3ba0: 27bdffd0      addiu   sp,sp,-48
801d3ba4: afb10024      sw      s1,36(sp)
801d3ba8: afb00020      sw      s0,32(sp)
801d3bac: afbf0028      sw      ra,40(sp)
801d3bb0: 8ca20000      lw      v0,0(a1)
801d3bb4: 27b10010      addiu   s1,sp,16
801d3bb8: 02202021      move    a0,s1
801d3bbc: 10400009      beq     zr,v0,0x801d3be4
801d3bc0: 00a08021      move    s0,a1
801d3bc4: 0c07466a      jal     0x801d19a8
801d3bc8: 00000000      nop
801d3bcc: 8e050000      lw      a1,0(s0)
801d3bd0: 02202021      move    a0,s1
801d3bd4: 0c0a1e25      jal     0x80287894
801d3bd8: 24060008      addiu   a2,zr,8
801d3bdc: 1440000b      bne     zr,v0,0x801d3c0c
801d3be0: 00401821      move    v1,v0
801d3be4: 8e020004      lw      v0,4(s0)
801d3be8: 00001821      move    v1,zr
801d3bec: 00402821      move    a1,v0

ちょっと、実行して様子を見てみますかね。

GXemul> step 20
801d3ba0: 27bdffd0      addiu   sp,sp,-48
801d3ba4: afb10024      sw      s1,36(sp)       [0xc647deec]
801d3ba8: afb00020      sw      s0,32(sp)       [0xc647dee8]
801d3bac: afbf0028      sw      ra,40(sp)       [0xc647def0]
801d3bb0: 8ca20000      lw      v0,0(a1)        [0xc647df70]
801d3bb4: 27b10010      addiu   s1,sp,16
801d3bb8: 02202021      move    a0,s1
801d3bbc: 10400009      beq     zr,v0,0x801d3be4
801d3bc0: 00a08021 (d)  move    s0,a1
801d3bc4: 0c07466a      jal     0x801d19a8
801d3bc8: 00000000 (d)  nop
<0x801d19a8(0xc647ded8,"h",0xc647df68,0x7df08c40,..)>
801d19a8: 27bdffd8      addiu   sp,sp,-40
801d19ac: afb00020      sw      s0,32(sp)       [0xc647dec0]
801d19b0: 00808021      move    s0,a0
801d19b4: afbf0024      sw      ra,36(sp)       [0xc647dec4]
801d19b8: 0c07463e      jal     0x801d18f8
801d19bc: 27a40010 (d)  addiu   a0,sp,16
  <0x801d18f8(0xc647deb0,"h",0xc647df68,0x7df08c40,..)>
801d18f8: 27bdffe8      addiu   sp,sp,-24
801d18fc: afb00010      sw      s0,16(sp)       [0xc647de98]
801d1900: afbf0014      sw      ra,20(sp)       [0xc647de9c]
801d1904: 0c074589      jal     0x801d1624
801d1908: 00808021 (d)  move    s0,a0
    <0x801d1624(0xc647deb0,"h",0xc647df68,0x7df08c40,..)>
801d1624: 27bdffd0      addiu   sp,sp,-48
801d1628: afb60028      sw      s6,40(sp)       [0xc647de80]

所々に出て来る (d) って、何かと思って調べてみたら、cpu_mips.cc に答えが載ってて、遅延 スロットで処理されましたの印でした。脇道はともかくとして、最初のjalで、0x801d18f8を訪れてますなあ。これって何?

[sakae@secd ~/pmax/src/sys]$ grep 801d19a8 netbsd.map
                0x00000000801d19a8                microtime

ソースも見てみるか。

sys_gettimeofday(struct lwp *l, const struct sys_gettimeofday_args *uap,
    register_t *retval)
{
        /* {
                syscallarg(struct timeval *) tp;
                syscallarg(void *) tzp;         really "struct timezone *";
        } */
        struct timeval atv;
        int error = 0;
        struct timezone tzfake;

        if (SCARG(uap, tp)) {
                microtime(&atv);
                error = copyout(&atv, SCARG(uap, tp), sizeof(atv));
                if (error)
                        return (error);
        }
        if (SCARG(uap, tzp)) {
                /*
                 * NetBSD has no kernel notion of time zone, so we just
                 * fake up a timezone struct and return it if demanded.
                 */
                tzfake.tz_minuteswest = 0;
                tzfake.tz_dsttime = 0;
                error = copyout(&tzfake, SCARG(uap, tzp), sizeof(tzfake));
        }
        return (error);
}

なる程、いかいもってコードになってるな。copyoutってのは、カーネルからユーザーの元へ データを転送するルーチンだろうな。そして、肝心のmicrotimeだけど、mapファイル経由で、 kern_tc.cにあると知った。

芋蔓式にソースを追いかける事になるのかな。こういう時は、gdbのお世話になりたいぞ。でも、 GXemulの環境じゃ、そういうのは夢のまた夢。

方針転換して、MIPSにこだわらず、i386以外のRISC系でNetBSDが動かんかなあ。例のパンフレットを 見てたら、QEMUでsparcが動くんですって。そうだ、それで行ってみよう。

qeum de sparc

河岸をArchLinuxに変えます。だって、この間落としてきたqemuのソースが置いてあるから。

[sakae@archbang qemu_git]$ ./configure  --disable-vnc --target-list=sparc-softmmu

sparc64版も作っておこうかと一瞬思ったけど、そんな無謀な事は止めた。土台が32Bitマシンで 64Bitマシンをエミュレーションなんかしたら、遅い事は目に見えてるからね。そうでなくても、 十分に遅いんだから。(文句は禁句でっせ)

sparc版は、どんな箱のふりを演じてくれるのかなあ? ちょいと調べてみる。

[sakae@archbang SPARC]$ qemu-system-sparc -M ?
Supported machines are:
leon3_generic        Leon-3 generic
SS-5                 Sun4m platform, SPARCstation 5 (default)
SS-10                Sun4m platform, SPARCstation 10
SS-600MP             Sun4m platform, SPARCserver 600MP
SS-20                Sun4m platform, SPARCstation 20
Voyager              Sun4m platform, SPARCstation Voyager
LX                   Sun4m platform, SPARCstation LX
SS-4                 Sun4m platform, SPARCstation 4
SPARCClassic         Sun4m platform, SPARCClassic
SPARCbook            Sun4m platform, SPARCbook
SS-1000              Sun4d platform, SPARCserver 1000
SS-2000              Sun4d platform, SPARCcenter 2000
SS-2                 Sun4c platform, SPARCstation 2

ピザボックスなSS5とかは有るけど、IPXとかの宝石箱は、さすがに古すぎてもう出回らないのか。 そんじゃ、NetBSDなサイトへ行って、ISOを落として くる。

[sakae@archbang SPARC]$ qemu-img create -f qcow2 sparc-5.0.2.img 3G

土台を作ります。

[sakae@archbang SPARC]$ qemu-system-sparc -M SS-10 -m 128M -cdrom sparccd.iso -hda sparc-5.0.2.img -nographic -boot d

NetBSDのインストール中に、端末は sun かって聞いてきるので、迷わずxtermでっせと答える事。 間違った端末だと、画面制御が正しく行われず、画面がぐちゃぐちゃになってしまう。 インストールには時間がかかるので、のんびとやってください。

次は、ソースファイルをどうやってピザボックスの中へ入れるかだな。箱の中には勿論NICが 有るから、やっぱりネットワーク経由だね。

その前に、一度、火を入れてみる。下記は、dmesgの一部。

NetBSD 5.0.2 (GENERIC) #0: Sat Feb  6 22:12:02 UTC 2010
        builds@b8.netbsd.org:/home/builds/ab/netbsd-5-0-2-RELEASE/sparc/20100206
1851Z-obj/home/builds/ab/netbsd-5-0-2-RELEASE/src/sys/arch/sparc/compile/GENERIC
total memory = 111 MB
avail memory = 104 MB
timecounter: Timecounters tick every 10.000 msec
bootpath: /iommu0/sbus0/espdma0/esp0/sd@0,0
mainbus0 (root): SUNW,SPARCstation-10: hostid 72000000
cpu0 at mainbus0: TMS390Z50 v0 or TMS390Z55 @ 170 MHz, on-chip FPU
cpu0: physical 20K instruction (64 b/l), 16K data (32 b/l), 1024K external (32 b
/l): cache enabled
obio0 at mainbus0
clock0 at obio0 slot 0 offset 0x200000: mk48t08
timer0 at obio0 slot 0 offset 0x300000: delay constant 43, frequency = 2000000 Hz
timecounter: Timecounter "timer-counter" frequency 2000000 Hz quality 100
  :
le0 at ledma0 slot 15 offset 0xc00000 level 6: address 52:54:00:12:34:56
le0: 8 receive buffers, 2 transmit buffers

次に、dhcpで、アドレスを取得する。DHCPサーバーは、QEMUが持ってて、NATもやってくれるようだ。 詳しくは、 KVMの導入と基本的な使い方 あたりが参考になるかな。

ss10# dhclient le0
Internet Systems Consortium DHCP Client V3.0.3
Copyright 2004-2005 Internet Systems Consortium.
All rights reserved.
For info, please visit http://www.isc.org/products/DHCP

Listening on BPF/le0/52:54:00:12:34:56
Sending on   BPF/le0/52:54:00:12:34:56
Sending on   Socket/fallback
DHCPREQUEST on le0 to 255.255.255.255 port 67
DHCPACK from 10.0.2.2
bound to 10.0.2.15 -- renewal in 39770 seconds.

これで、箱の中から外へは行けるようになる。けど、外から中へも行きたいよね。丁度、仮想箱 みたいにね。

[sakae@archbang SPARC]$ cat boot
#!/bin/sh

qemu-system-sparc -M SS-10 -m 128M -hda sparc-5.0.2.img -nographic -boot c \
  -redir tcp:2222::22

リダイレクトってオプションを付けてあげるとOK。

[sakae@archbang ~]$ scp -P 2222 syssrc.tgz localhost:
Password:
syssrc.tgz                                    100%   36MB 241.5KB/s   02:31

こんな風に、Linux側から箱の中と通信出来るようになる。

そんじゃ、記念にスパーク語を眺めてみる。

int macronamep(int sym){
   1ec14:       9d e3 bf 88     save  %sp, -120, %sp
   1ec18:       f0 27 a0 44     st  %i0, [ %fp + 0x44 ]
        int val;

    val = assq(sym,G);
   1ec1c:       03 00 13 5e     sethi  %hi(0x4d7800), %g1
   1ec20:       82 10 63 44     or  %g1, 0x344, %g1     ! 4d7b44 <G>
   1ec24:       c2 00 40 00     ld  [ %g1 ], %g1
   1ec28:       d0 07 a0 44     ld  [ %fp + 0x44 ], %o0
   1ec2c:       92 10 00 01     mov  %g1, %o1
   1ec30:       7f ff f9 08     call  1d050 <assq>
   1ec34:       01 00 00 00     nop
   1ec38:       82 10 00 08     mov  %o0, %g1
   1ec3c:       c2 27 bf f4     st  %g1, [ %fp + -12 ]
    if(val == 0)
   1ec40:       c2 07 bf f4     ld  [ %fp + -12 ], %g1
   1ec44:       80 a0 60 00     cmp  %g1, 0
   1ec48:       12 80 00 05     bne  1ec5c <macronamep+0x48>
   1ec4c:       01 00 00 00     nop
        return(0);
   1ec50:       c0 27 bf ec     clr  [ %fp + -20 ]
   1ec54:       10 80 00 15     b  1eca8 <macronamep+0x94>
   1ec58:       01 00 00 00     nop

    if(IS_MACRO(cdr(val)))
   1ec5c:       d0 07 bf f4     ld  [ %fp + -12 ], %o0
   1ec60:       7f ff f8 4a     call  1cd88 <cdr>
   1ec64:       01 00 00 00     nop
   1ec68:       84 10 00 08     mov  %o0, %g2
   1ec6c:       03 00 01 0f     sethi  %hi(0x43c00), %g1
   1ec70:       86 10 61 08     or  %g1, 0x108, %g3     ! 43d08 <memory>
   1ec74:       82 10 00 02     mov  %g2, %g1
   1ec78:       85 28 60 04     sll  %g1, 4, %g2
   1ec7c:       83 28 a0 02     sll  %g2, 2, %g1
   1ec80:       82 20 40 02     sub  %g1, %g2, %g1
   1ec84:       c2 00 c0 01     ld  [ %g3 + %g1 ], %g1
   1ec88:       80 a0 60 10     cmp  %g1, 0x10
   1ec8c:       12 80 00 06     bne  1eca4 <macronamep+0x90>
   1ec90:       01 00 00 00     nop
        return(1);
   1ec94:       82 10 20 01     mov  1, %g1     ! 1 <_init-0x10b53>
   1ec98:       c2 27 bf ec     st  %g1, [ %fp + -20 ]
   1ec9c:       10 80 00 03     b  1eca8 <macronamep+0x94>
   1eca0:       01 00 00 00     nop
    else
        return(0);
   1eca4:       c0 27 bf ec     clr  [ %fp + -20 ]
   1eca8:       c2 07 bf ec     ld  [ %fp + -20 ], %g1
}
   1ecac:       b0 10 00 01     mov  %g1, %i0
   1ecb0:       81 e8 00 00     restore
   1ecb4:       81 c3 e0 08     retl
   1ecb8:       01 00 00 00     nop

うーん、MIPSみたいに直感的に分からんな。何はなくとも sparc V8 instraction set ちゅう、マニュアルだな。なお、V9ってのが64Bit版。余談だけど、SPARC64 VIIIfx ってやつは、 京コンピュータに9万個も使われてる、富士通特製のスパークだ。

syscall for sparc

MIPSでやった、gettimeofdayを、ユーザーランド側から眺めてみます。

(gdb) disassemble gettimeofday
Dump of assembler code for function gettimeofday:
0x000173bc <gettimeofday+0>:    mov  0x474, %g1 ! 0x474
0x000173c0 <gettimeofday+4>:    add  %o7, 8, %g2
0x000173c4 <gettimeofday+8>:    ta  0
0x000173c8 <gettimeofday+12>:   sethi  %hi(0x1ac00), %g1
0x000173cc <gettimeofday+16>:   or  %g1, 0xf0, %g1      ! 0x1acf0 <__cerror>
0x000173d0 <gettimeofday+20>:   jmp  %g1
0x000173d4 <gettimeofday+24>:   nop
End of assembler dump.

ta ってのが、カーネルを叩く命令なんですかね? って、ちゃんとマニュアル嫁よ。 それにしても、意味不っぽいコードだな。

そんじゃ、カーネルの中側を見たいな。えっと、gdbを使おうとしてたんだ。 おあつらえ向きな、 GDB を使い NetBSD カーネルをデバッグする HOWTO なんてのが有ったので、やってみる。

まずは、ターゲット機のカーネルにgdb用のインターフェースを埋め込むんだな。はいはい、やって みますよ。

  :
#   compile  GENERIC/kgdb_stub.o
cc -mno-fpu -ffreestanding -fno-zero-initialized-in-bss -g -O2 -std=gnu99 -fno-strict-aliasing -Werror -Wall -Wno-main -Wno-format-zero-length -Wpointer-arith -Wmissing-prototypes -Wstrict-prototypes -Wswitch -Wshadow -Wcast-qual -Wwrite-strings -Wno-unreachable-code -Wno-sign-compare -Wno-pointer-sign -Wno-attributes -Werror -I. -I../../../../../common/include -I../../../../arch -I../../../.. -nostdinc -DRASTERCONSOLE -DLKM -DDEBUG -DMAXUSERS=32 -D_KERNEL -D_KERNEL_OPT -I../../../../lib/libkern/../../../common/lib/libc/quad -I../../../../lib/libkern/../../../common/lib/libc/string -I../../../../lib/libkern/../../../common/lib/libc/arch/sparc/string -I../../../../dist/ipf -c ../../../../kern/kgdb_stub.c
../../../../kern/kgdb_stub.c: In function 'kgdb_trap':
../../../../kern/kgdb_stub.c:499: error: invalid lvalue in assignment
../../../../kern/kgdb_stub.c:519: error: invalid lvalue in assignment
*** Error code 1

エラーになってるのは、次の行。

         PC_REGS(regs) = addr;

型が合わないんかなと思って、型変換の指示をしてみたけど、だめみたい。やっぱり、sparcなんて 骨董品の部類で、よくdebugされていないのかな?

1000歩後退して、DDBだけでも使えないかとコンパイルしてみた。

#      link  GENERIC/netbsd
#      ld -Map netbsd.map --cref -n -T ../../../../arch/sparc/conf/kern.ldscript
 -Ttext F0004000 -e start -X -S -o netbsd ${SYSTEM_OBJ} ${EXTRA_OBJ} vers.o
#      NetBSD 5.0.2 (SAKAE-$Revision: 1.205 $) #0: Sat Jul 21 16:39:00 JST 2012
#         text    data     bss     dec     hex filename
#         3637813  107840  361228 4106881  3eaa81 netbsd

けど、DDBへの入り方が分からん。ddb(4)を見ても、実機(≠ QEMU)の事しか書いてないし。

ENTERING THE DEBUGGER
     Unless DDB_ONPANIC is set to 0, ddb will be activated whenever the kernel
     would otherwise panic.

     ddb may also be activated from the console.  In general, sending a break
     on a serial console will activate ddb.  There are also key sequences for
     each port that will activate ddb from the keyboard:
           sparc     <L1>-A, or <Stop>-A on a Sun keyboard.
                     <Break> on serial console.
           sparc64   <L1>-A, or <Stop>-A on a Sun keyboard.
                     <Break> on serial console.

でもヒントが書かれていた。

     The key sequence to activate ddb can be changed by modifying
     ``hw.cnmagic'' with sysctl(8).  If the console is not dedicated to ddb
     the sequence should not be easily typed by accident.  In addition, ddb
     may be explicitly activated by the debugging code in the kernel if DDB is
     configured.

確認してみる。

ss10# sysctl hw.cnmagic
hw.cnmagic = \x27\x01
ss10# sysctl -a |grep ddb
ddb.radix = 16
ddb.maxoff = 1048576
ddb.maxwidth = 80
ddb.lines = 24
ddb.tabstops = 8
ddb.onpanic = 0
ddb.fromconsole = 1
ddb.tee_msgbuf = 0
ddb.commandonenter =

ちょいと実験してみる。

ss10# sysctl -w hw.cnmagic=~~
mag 0 7e:1
mag 1 7e:7f
hw.cnmagic: \x78\x37\x65\x78\x37\x65 -> \x7e\x7e
ss10# ~Stopped in pid 0.2 (system) at  netbsd:cpu_Debugger+0x4:        or              %
o7, %g0, %g1
db> help
b               d               machine         s               trace
break           delete          match           search          until
bt              dmesg           next            set             w
c               dwatch          p               show            watch
call            examine         print           sifting         whatis
callout         help            ps              step            write
continue        kill            reboot          sync            x

ddbを呼び出す文字列をチルダ2個に設定。そして、入力してみたら、ddbが表れてくれたよ。 後は、この設定と、ddbの調整値を、/etc/sysctl.confにでも書いておけばいいんだな。

db> trace
cpu_Debugger(0x800, 0xf3921008, 0xf073062e, 0xf039dc00, 0x0, 0xf039dc00) at netb
sd:zsc_intr_hard+0x140
zsc_intr_hard(0xf392a808, 0x0, 0x16eb4, 0xf03dd928, 0x0, 0xb4) at netbsd:zshard+
0x3c
zshard(0x0, 0xf029c890, 0xf00, 0x408000e5, 0xffff, 0xb3) at netbsd:sparc_interru
pt44c+0x19c
sparc_interrupt44c(0x1, 0xf0293928, 0xf0002000, 0x0, 0xffff, 0xb00) at netbsd:kp
reempt_enable+0x20
kpreempt_enable(0x1, 0xf0293928, 0xf0002000, 0x0, 0xb28f648c, 0x1ac284cb) at net
bsd:sched_curcpu_runnable_p+0x3c
sched_curcpu_runnable_p(0x0, 0x0, 0xc, 0x0, 0xffffffff, 0x606) at netbsd:idle_lo
op+0xe4
idle_loop(0xf37c7c80, 0xf37c7c80, 0xf03f6800, 0xf0228800, 0xf3912130, 0xf03e1000
) at netbsd:lwp_trampoline+0x8
db> break sys_gettimeofday
db> show break
 Map      Count    Address
*0xf03dc148     1    netbsd:sys_gettimeofday
db> cont

結局、ddbの呼び出し文字列は、+DDB にした。ddbが起動した時、traceを撮るように設定。

ss10$ ./a.out
Breakpoint in pid 297.1 (a.out) at  netbsd:sys_gettimeofday:    save        %sp
, -0x78, %sp
sys_gettimeofday(0x474, 0xf434efb0, 0x173c4, 0xf434efb0, 0xf434edfc, 0x0) at 0x
f0008a7c
db> x/i $pc,10
netbsd:sys_gettimeofday:    save        %sp, -0x78, %sp
netbsd:sys_gettimeofday+0x4:    add         %fp, -0x10, %i0
netbsd:sys_gettimeofday+0x8:    ld          [%i1 + %g0], %g1
netbsd:sys_gettimeofday+0xc:    subcc       %g1, 0x0, %g0
netbsd:sys_gettimeofday+0x10:   be          netbsd:sys_gettimeofday+0x3c
netbsd:sys_gettimeofday+0x14:   or          %g0, %i0, %o0
netbsd:sys_gettimeofday+0x18:   call        netbsd:microtime
netbsd:sys_gettimeofday+0x1c:   nop
netbsd:sys_gettimeofday+0x20:   or          %g0, 0x8, %o2
netbsd:sys_gettimeofday+0x24:   or          %g0, %i0, %o0
netbsd:sys_gettimeofday+0x28:   call        netbsd:copyout
netbsd:sys_gettimeofday+0x2c:   ld          [%i1 + %g0], %o1
netbsd:sys_gettimeofday+0x30:   subcc       %o0, 0x0, %g0
netbsd:sys_gettimeofday+0x34:   bne         netbsd:sys_gettimeofday+0x60
netbsd:sys_gettimeofday+0x38:   nop
netbsd:sys_gettimeofday+0x3c:   ld          [%i1 + 0x4], %o1
db> machine proc
LWP 0xf437fa80: PID:308.1 CPU:0 stat:7 vmspace:0xf37d87e0 ctx: 0xf0471a60 cpuse
t 0
pmap:0xf4387040 wchan:0x0 pri:43 epri:43
maxsaddr:0xee000000 ssiz:2 pg or 2000B
profile timer: 0 sec 0 usec
pcb: 0xf433e000

やっと、GXemul並みになったな。嗚呼、breakをシンボルで貼れるだけ、GXemulより進歩してるか。 なんて安心しながら操作してたら、、、

db> n
After 15 instructions (4 loads, 0 stores),
Stopped in pid 308.1 (a.out) at netbsd:timer_get_timecount+0x80:    jmpl        [%o7 + 0x8], %g0
db> n
After 279 instructions (24 loads, 15 stores),
Stopped in pid 308.1 (a.out) at netbsd:tc_windup+0x444: jmpl        [%i7 + 0x8], %g0
db> n
After 81 instructions (10 loads, 4 stores),
Stopped in pid 308.1 (a.out) at netbsd:statintr_4m+0xa0:    jmpl        [%i7 + 0x8], %g0
db> n
qemu: fatal: Trap 0x81 while interrupts disabled, Error state
pc: f00099e4  npc: f00099e8
General Registers:
%g0-7: 00000000 404000e0 f0002000 00000a00 f03a05a0 00000000 00000000 00000000

Current Register Window:
%o0-7: 00000081 40000ec6 f0008ee0 f038fd18 0000ffff f038fc40 f038fcb8 f00088c8
%l0-7: 40000ec6 f0008ee0 f00099e4 00000000 00000001 f038c540 f0002000 00000000
%i0-7: 00000001 f0293854 f0002000 00000001 001dabea aff0f1ff f038fd68 f0008e7c

Floating Point Registers:
%f00: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff
%f08: 3c8400003c75c28f 4404000000008000 3f8eb851e0000000 ffffffffffffffff
%f16: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff
%f24: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff
psr: 40000ec6 (icc: ---- SPE: SP-) wim: 00000080
fsr: 00000820 y: 00000000
./boot: line 4:   546 Aborted                 qemu-system-sparc -M SS-10 -m 128M -hda sparc-5.0.2.img -nographic -boot c -redir tcp:2222::22
[sakae@archbang SPARC]$

タイミング的にシビアな部分を見てたんで、OSが割り込み関係が想定外って認識しちゃったのかな?