APC8750にNetBSD/evbarmを移植するための記録 10/7
2014/01/26(日) 25:04 NetBSD はてブ情報 はてブに登録 はてブ数

つまらんミスで動いてなかった。
if(hoge)
    return 0;
というのをprintf debugした際に
if(hoge)
    printf(piyo);
    return 0;
としていた。中かっこが足らないのだ。初心者かよ!

いざ、実行。
sys_execve
sys_execve: eror = -2
cnopen: minor
cnopen: cn_tab == NULL?
cnopen: cndev=000fff00
cnopen: cndev == NODEV?
cnopen: dev == cndev?
cnopen: cn_devvp == NULLVP? unit=0
cnopen: cdevvp()
cnopen: cdevvp() error=0
cnopen: vn_lock()
cnopen: vn_lock error=0
cnopen: VOP_OPEN cndevvp[0]=c1bf2a50
cnopen: VOP_UNLOCK error=6
openが6を返している。エラーコードが6というとENXIOとのこと。
#define    ENXIO        6        /* Device not configured */
じゃぁ、cndevvp[0]=c1bf2a50のc1bf2a50ってなんだよ、とnetbsd.mapを見てみると
.text          0x00000000c0184c64      0x4e0 wmt_com.o
                0x00000000c0184c64                wmtcomcnpollc
                0x00000000c0184c6c                wmtcomstop
                0x00000000c0184c78                wmtcomioctl
                0x00000000c0184c98                wmtcompoll
                0x00000000c0184cb8                wmtcomwrite
                0x00000000c0184cd8                wmtcomread
                0x00000000c0184cf8                wmtcomclose
                0x00000000c0184d18                wmtcomopen

ということでハズしている。後で確認したが、objdump -dでみたら、netbsd.mapとも違う数字になっていた。なんだこりゃ。


VOP_OPENをもう少し表示させてみる。
sys_execve: eror = -2
VOP_OPEN: vp=c1bf2c60, VOFFSET(vop_open)=00000005
cnopen: minor
cnopen: cn_tab == NULL?
cnopen: cndev=000fff00
cnopen: cndev == NODEV?
cnopen: dev == cndev?
cnopen: cn_devvp == NULLVP? unit=0
cnopen: cdevvp()
cnopen: cdevvp() error=0
cnopen: vn_lock()
cnopen: vn_lock error=0
cnopen: VOP_OPEN cndevvp[0]=c1bf2a50
VOP_OPEN: vp=c1bf2a50, VOFFSET(vop_open)=00000005
cnopen: VOP_UNLOCK error=6
わかんないな。ん? なんだ、c1bf2c60というのがcnopenの前に出てるぞ?
VOP_OPENがcnopen経由以外で呼ばれているってことか。それっぽいのは以下あたり?
  • vfs_mount.cのvfs_mountroot(void)
  • tty_tty.cのcttyopen(dev_t dev, int flag, int mode, struct lwp *l)
ちがうかな?init.cのopenlogかもしれん。

と思ったが、ramdisk.fsだとインストーラように小さくするため、きっと#ifndef LETS_GET_SMALLのはずだから違うか。

とりあえず、本当は誰が呼んでるかわからんからpanicさせてみるかなぁ。
rn_init: radix functions require max_keylen be set
start_init
module_init_class
boot device: <unknown>
root on md0a dumps on md0b
VOP_OPEN: vp=c1bf2f20, VOFFSET(vop_open)=00000005
VOP_OPEN: error=0
panic: VOP_OPEN
Stopped in pid 0.1 (system) at  netbsd:cpu_Debugger+0x4:        bx      r14
0xc06b1f24: netbsd:vpanic+0xc
0xc06b1f3c: netbsd:printf_nolog
0xc06b1f70: netbsd:VOP_OPEN+0x70
0xc06b1f9c: netbsd:vfs_mountroot+0x280
0xc06b1fec: netbsd:main+0x350
0xc06b1ffc: netbsd:kernel_text+0x50
db>
ふむ。やはりvfs_mountroot。

じゃぁ、cnopenは?
root on md0a dumps on md0b
VOP_OPEN: vp=c1bf2f20, VOFFSET(vop_open)=00000005
VOP_OPEN: error=0
mountroot: trying nfs...
mountroot: trying msdos...
mountroot: trying ffs...
root file system type: ffs
configure3
inittodr
WARNING: no TOD clock present
WARNING: using filesystem time
WARNING: CHECK AND RESET THE DATE!
uvm_swap_init
VOP_OPEN: vp=c1bf2dc0, VOFFSET(vop_open)=00000005
VOP_OPEN: error=0
uvm_scheduler
init: copying out flags `-s' 3
init: copying out path `/sbin/init' 11
move out arg pinters
sys_execve
VOP_OPEN: vp=c1bf2b00, VOFFSET(vop_open)=00000005
VOP_OPEN: error=0
sys_execve: eror = -2
VOP_OPEN: vp=c1bf2c60, VOFFSET(vop_open)=00000005
cnopen: minor
cnopen: cn_tab == NULL?
cnopen: cndev=000fff00
cnopen: cndev == NODEV?
cnopen: dev == cndev?
cnopen: cn_devvp == NULLVP? unit=0
cnopen: cdevvp()
cnopen: cdevvp() error=0
cnopen: vn_lock()
cnopen: vn_lock error=0
cnopen: VOP_OPEN cndevvp[0]=c1bf2a50
VOP_OPEN: vp=c1bf2a50, VOFFSET(vop_open)=00000005
VOP_OPEN: error=6
cnopen: VOP_UNLOCK error=6
panic: cnopen
Stopped in pid 1.1 (init) at    netbsd:cpu_Debugger+0x4:        bx      r14
0xca86cc80: netbsd:vpanic+0xc
0xca86cc98: netbsd:printf_nolog
0xca86ccd4: netbsd:cnopen+0x16c
0xca86ccfc: netbsd:cdev_open+0x68
0xca86cd4c: netbsd:spec_open+0x198
0xca86cd70: netbsd:VOP_OPEN+0x98
0xca86ce24: netbsd:vn_open+0x1dc
0xca86ce9c: netbsd:do_open+0xb0
0xca86cecc: netbsd:do_sys_openat+0x7c
0xca86cef0: netbsd:sys_open+0x34
0xca86cf84: netbsd:syscall+0x88
0xca86cfac: netbsd:swi_handler+0x98
db>
うん。swi_handlerでした。

読めば読むほどinit.cのprint_consoleどうにもできる気がしない。

ということで、このpanicさせるopenシステムコールを少しずつ動かして、どこまで進んでいるかを見れば、どこで止まっているかはわかる。

どうやら、sbin/init/init.c#771の場所。single_user()の中で使われているwaitpid()が帰ってきていないようだ。
    771 	requested_transition = 0;
    772 	do {
    773 		if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
    774 			collect_child(wpid, status);
というか、そのまえのfork()が失敗しているということである。
kernelのfork1は成功して/sbin/initが実行されているのだけれど、forkはうまく動いていないようだ。
とにかく、いろいろおかしいことがわかってきた。こういう時、どうデバックしたらいいのか。
まずは、forkが失敗しようがしまいが、進めてしまうとどうなるのだろうか。
sys_execve
VOP_OPEN: vp=c1bf2b00, VOFFSET(vop_open)=00000005
VOP_OPEN: error=0
sys_execve: error = -2
proc: table is full - increase kern.maxproc or NPROC
しばらくして上のproc: table is full - ... が出た。なんか、ループして食いつぶしたような感じである。

とにかくだ、シリアル動かないとにっちもさっちも。やっぱりprint_console動かす方向に戻す。

VOP_OPENを追っかけると、vpではなくvp->v_opが大事そうである。
つまり、vp->v_op[offset]が関数ポインタとして実行されるのである。
ということで、vp->v_opを表示させるようにしてみる。
VOP_OPEN: vp=c1bf2a50, vp->v_op=c1a35d28, VOFFSET(vop_open)=00000005
VOP_OPEN: error=6
cnopen: VOP_UNLOCK error=6
panic: cnopen
Stopped in pid 1.1 (init) at    netbsd:cpu_Debugger+0x4:        bx      r14
0xca86cc80: netbsd:vpanic+0xc
0xca86cc98: netbsd:printf_nolog
0xca86ccd4: netbsd:cnopen+0x16c
0xca86ccfc: netbsd:cdev_open+0x68
0xca86cd4c: netbsd:spec_open+0x198
0xca86cd70: netbsd:VOP_OPEN+0xa0
0xca86ce24: netbsd:vn_open+0x1e8
0xca86ce9c: netbsd:do_open+0xb0
0xca86cecc: netbsd:do_sys_openat+0x7c
0xca86cef0: netbsd:sys_open+0x34
0xca86cf84: netbsd:syscall+0x88
0xca86cfac: netbsd:swi_handler+0x98
db>
とはいうものの、c1a35d28はobjdumpしても見つからない。
よく考えたら、アドレスがわかっても意味なくって、アドレスに格納されている値が大事なのでは?

まてよ、そういえばコンソールから入力できるようになっているので、ddbが使えるということでは?!

man ddbしてみると、いくつかのコマンドが打てる。
psとかやってみる。
db> ps
PID    LID S CPU     FLAGS       STRUCT LWP *               NAME WAIT
2        1 2   0         0           c1a3b540               init
1    >   1 7   0         0           c1be8aa0               init
0       30 3   0       200           c1a3b2a0           aiodoned aiodoned
0       29 3   0       200           c1be8d40            ioflush syncer
0       28 3   0       200           c1a3b000           pgdaemon pgdaemon
0       25 3   0       200           c1be8800              unpgc unpgc
0       24 3   0       200           c1be8560        vmem_rehash vmem_rehash
0       15 3   0       200           c1a3ba80         pmfsuspend pmfsuspend
0       14 3   0       200           c1a3bd20           pmfevent pmfevent
0       13 3   0       200           c1a34020         sopendfree sopendfr
0       12 3   0       200           c1a342c0           nfssilly nfssilly
0       11 3   0       200           c1a34560            cachegc cachegc
0       10 3   0       200           c1a34800              vrele vrele
0        9 3   0       200           c1a34aa0             vdrain vdrain
0        8 3   0       200           c1a34d40          modunload mod_unld
0        7 3   0       200           c1a2b000            xcall/0 xcall
0        6 1   0       200           c1a2b2a0          softser/0
0        5 1   0       200           c1a2b540          softclk/0
0        4 1   0       200           c1a2b7e0          softbio/0
0        3 1   0       200           c1a2ba80          softnet/0
0        2 1   0       201           c1a2bd20             idle/0
0        1 3   0       200           c029b120            swapper uvm
db>
おぉー、プロセスがけっこう動いているみたいじゃないか。

アドレスの中身を除くのはexamineのようだ。

本題に戻ってc1a35d28つまりvp->v_opから先頭を10こ表示させてみる。
db> examine /x c1a35d28,10
c1a35d28:       c0167b48    c01640b8    c00d77c8    c00402ec    c00402ec    c00d
85f8    c00d7944    c004047c    c004047c    c004047c    c00d82dc    c00d7f74
c1a35d58:       c00d7e40    c00402d8    c00d7da4    c00d7d78
db>
ほうほう。VOFFSET(vop_open)=00000005だった。配列は0から始まるので6個目がそれにあたる。
つまり、改行しているところにある値がそれで、c00d85f8である。
これをobjdumpの結果にgrepしてみる。
c00d85f8 <spec_open>:
c00d85f8:       e1a0c00d        mov     ip, sp
c00d85fc:       e92ddff0        push    {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
c00d8600:       e24cb004        sub     fp, ip, #4
c00d8604:       e24dd024        sub     sp, sp, #36     ; 0x24
c00d8608:       e1a06000        mov     r6, r0
c00d860c:       ee1d3f90        mrc     15, 0, r3, cr13, cr0, {4}
c00d8610:       e5904004        ldr     r4, [r0, #4]
c00d8614:       e5933178        ldr     r3, [r3, #376]  ; 0x178
c00d8618:       e5945098        ldr     r5, [r4, #152]  ; 0x98
c00d861c:       e50b3034        str     r3, [fp, #-52]  ; 0x34
c00d8620:       e5943064        ldr     r3, [r4, #100]  ; 0x64
c00d8624:       e595800c        ldr     r8, [r5, #12]
c00d8628:       e3530000        cmp     r3, #0
c00d862c:       e595a010        ldr     sl, [r5, #16]
c00d8630:       e5959004        ldr     r9, [r5, #4]
おぉ、関数名にopenがついてそれっぽいぞ!

spec_openは[sys/miscfs/specfs/spec_vnops.c#spec_open]にある。

sys/kern/vfs_subr.c#cdevvpにあったgetdevvpにVCHRが与えられていたことから、
    352 int
    353 cdevvp(dev_t dev, vnode_t **vpp)
    354 {
    355 
    356     return (getdevvp(dev, vpp, VCHR));
    357 }
このブロックがひじょーに怪しいな。device not configuredのENXIOという記述もあるし。
    531     switch (vp->v_type) {
    532     case VCHR:
    533         error = kauth_authorize_device_spec(ap->a_cred, req, vp);
    534         if (error != 0)
    535             return (error);
    536 
    537         /*
    538          * Character devices can accept opens from multiple
    539          * vnodes.
    540          */
    541         mutex_enter(&device_lock);
    542         if (sn->sn_gone) {
    543             mutex_exit(&device_lock);
    544             return (EBADF);
    545         }
    546         sd->sd_opencnt++;
    547         sn->sn_opencnt++;
    548         mutex_exit(&device_lock);
    549         if (cdev_type(dev) == D_TTY)
    550             vp->v_vflag |= VV_ISTTY;
    551         VOP_UNLOCK(vp);
    552         do {
    553             const struct cdevsw *cdev;
    554 
    555             gen = module_gen;
    556             error = cdev_open(dev, ap->a_mode, S_IFCHR, l);
    557             if (error != ENXIO)
    558                 break;
    559 
    560             /* Check if we already have a valid driver */
    561             mutex_enter(&device_lock);
    562             cdev = cdevsw_lookup(dev);
    563             mutex_exit(&device_lock);
    564             if (cdev != NULL)
    565                 break;
    566 
    567             /* Get device name from devsw_conv array */
    568             if ((name = cdevsw_getname(major(dev))) == NULL)
    569                 break;
    570 
    571             /* Try to autoload device module */
    572             (void) module_autoload(name, MODULE_CLASS_DRIVER);
    573         } while (gen != module_gen);
    574 
    575         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
    576         break;
ここがprintfで反応したらビンゴかもしれん。

ビンゴであった。
結局subr_devsw.cのcdevsw_lookup, cdev_openあたりにprintfを入れまくり。

ひさびさにバナーからログを残しておこう。 
init subsystems: stacks vectors undefined page pmap_physload pmap [ Kernel symbol table missing! ]
done.
Loaded initial symtab at 0xc01e431c, strtab at 0xc020453c, # entries 8211
pmap_postinit: Allocated 35 static L1 descriptor tables
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 6.99.23 (APC) #50: Mon Oct  7 17:28:43 UTC 2013
        root@builder.localdomain:/usr/obj/sys/arch/evbarm/compile/APC
total memory = 512 MB
avail memory = 495 MB
mainbus0 (root)
cpu0 at mainbus0 core 0: ARM1176JZ-S r0p7 (ARM11J V6ZK core)
cpu0: DC enabled IC enabled WB enabled LABT
cpu0: 16KB/32B 4-way L1 Instruction cache
cpu0: 16KB/32B 4-way write-back-locking-C L1 Data cache
vfp0 at cpu0: VFP11
obio0 at mainbus0
wmicu0 at obio0 addr 0xd8140000-0xd814ffff
icu-debug:
d8140040: 00000000 -> 00000000
d8140044: 00000000 -> 00000000
d8140048: 00000000 -> 00000000
d814004c: 00000000 -> 00000000
d8140050: 00000000 -> 00000000
d8140054: 00000000 -> 00000000
d8140058: 00000000 -> 00000000
d814005c: 00000000 -> 00000000
d8140060: 00000000 -> 00000000
d8140064: 00000000 -> 00000000
d8140068: 00000000 -> 00000000
d814006c: 00000000 -> 00000000
d8140070: 00000000 -> 00000000
d8140074: 00000000 -> 00000000
d8140078: 00000000 -> 00000000
d814007c: 00000000 -> 00000000
wmtmr0 at obio0 addr 0xd8100000-0xd810ffff intr 48 : WMT System Timer
wmtcom0 at obio0 addr 0xd8200000-0xd820ffff intr 32 : WMT UART
wmtcom:wmtcom_attach_subr
wmtcom:wmtcom_attach_subr 1
wmtcom:wmtcom_attach_subr 1-1
wmtcom:wmtcom_attach_subr 1-2
wmtcom:wmtcom_attach_subr 1-3
wmtcom:wmtcom_attach_subr 2
wmtcom:wmtcom_attach_subr 3
wmtcom:wmtcom_attach_subr 3-1
wmtcom0: console cn_tab->cn_dev=000fff00
icu: establish_irq: is->is_irq=0x20
icu: unblock: irqbase=0x00000020, irqmask=0x00000001, irq_num=32, reg=0x00000008
icu: establish_irq: is->is_irq=0x30
icu: unblock: irqbase=0x00000020, irqmask=0x00010000, irq_num=48, reg=0x00000008
rn_init: radix functions require max_keylen be set
start_init
module_init_class
boot device: <unknown>
root on md0a dumps on md0b
VOP_OPEN: vp=c1bf2f20, vp->v_op=c1a35d28, VOFFSET(vop_open)=00000005
spec_open: start
cdevsw_lookup: dev=00001200, cmajor = 18, cdevsw = c01e0350
spec_open: cdev_ioctl error=0
VOP_OPEN: error=0
mountroot: trying nfs...
mountroot: trying msdos...
mountroot: trying ffs...
root file system type: ffs
configure3
inittodr
WARNING: no TOD clock present
WARNING: using filesystem time
WARNING: CHECK AND RESET THE DATE!
uvm_swap_init
VOP_OPEN: vp=c1bf2dc0, vp->v_op=c1a35d28, VOFFSET(vop_open)=00000005
spec_open: start
cdevsw_lookup: dev=00000100, cmajor = 1, cdevsw = c01e0350
spec_open: cdev_type(dev) != D_DISK error=0
VOP_OPEN: error=0
uvm_scheduler
init: copying out flags `-s' 3
init: copying out path `/sbin/init' 11
move out arg pinters
sys_execve
VOP_OPEN: vp=c1bf2b00, vp->v_op=c1a35b68, VOFFSET(vop_open)=00000005
VOP_OPEN: error=0
sys_execve: error = -2
vn_open: pathstring=/dev/console
VOP_OPEN: vp=c1bf2c60, vp->v_op=c1a35a88, VOFFSET(vop_open)=00000005
spec_open: start
spec_open: VCHR
cdevsw_lookup: dev=00000200, cmajor = 2, cdevsw = c01e0350
cdevsw_lookup: dev=00000200, cmajor = 2, cdevsw = c01e0350
cdevsw_lookup: dev=00000200, cmajor = 2, cdevsw = c01e0350
cdev_open: d->d_open = c001034c, dev=00000200
cnopen: minor
cnopen: cn_tab == NULL?
cnopen: cndev=000fff00
cnopen: cndev == NODEV?
cnopen: dev == cndev?
cnopen: cn_devvp == NULLVP? unit=0
cnopen: cdevvp()
cnopen: cdevvp() error=0
cnopen: vn_lock()
cnopen: vn_lock error=0
cnopen: VOP_OPEN cndevvp[0]=c1bf2a50
VOP_OPEN: vp=c1bf2a50, vp->v_op=c1a35d28, VOFFSET(vop_open)=00000005
spec_open: start
spec_open: VCHR
cdevsw_lookup: dev=000fff00, cmajor = 4095, cdevsw = c01e0350
cdevsw_lookup: dev=000fff00, cmajor = 4095, cdevsw = c01e0350
cdevsw_lookup: dev=000fff00, cmajor = 4095, cdevsw = c01e0350
cdev_open: cdevsw_lookup() == NULL, dev=000fff00
spec_open: cdev_open error=6
cdevsw_lookup: dev=000fff00, cmajor = 4095, cdevsw = c01e0350
cdevsw_lookup: dev=000fff00, cmajor = 4095, cdevsw = c01e0350
spec_open: cdev_type(dev) != D_DISK error=6
VOP_OPEN: error=6
cnopen: VOP_UNLOCK error=6
panic: cnopen
Stopped in pid 1.1 (init) at    netbsd:cpu_Debugger+0x4:        bx      r14
0xca86cc80: netbsd:vpanic+0xc
0xca86cc98: netbsd:printf_nolog
0xca86ccd4: netbsd:cnopen+0x16c
0xca86ccfc: netbsd:cdev_open+0x78
0xca86cd4c: netbsd:spec_open+0x1b0
0xca86cd70: netbsd:VOP_OPEN+0xa0
0xca86ce24: netbsd:vn_open+0x1e8
0xca86ce9c: netbsd:do_open+0xb0
0xca86cecc: netbsd:do_sys_openat+0x7c
0xca86cef0: netbsd:sys_open+0x34
0xca86cf84: netbsd:syscall+0x88
0xca86cfac: netbsd:swi_handler+0x98
db>
結論から言えば、cdevsw[]に所望のデバイスが見つからない(lookupできない)のでエラーになっていた。
うまくlookupできているものとそうでないものを比較していてぴんときた。
cdevsw_lookup: dev=00000200, cmajor = 2, cdevsw = c01e0350
cdevsw_lookup: dev=000fff00, cmajor = 4095, cdevsw = c01e0350
そういえば、dev=000fff00って変だなと思っていて、wmt_com.cのattachでそれを作っていたのだった。
                /* locate the major number */
                maj = cdevsw_lookup_major(&wmtcom_cdevsw);

                cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev));
makedevはビットシフトしてintを作るだけなんだけど、majが怪しいってことですな。
で、それの元ネタになるのが&wmtcom_cdevswなわけで、デバイスのメジャー番号ってどこで定義するんだっけ? 自動的に決まるというはずはなくってどこかに書いたはずだけど、ということでgrep -i major しまくるとarch/arm/conf/majors.arm32にたどり着いた。
ここにはepcomなどのCPU固有のデバイスを含めて記述されている。wmtcomはここに書いていないからうまくlookupできないのに違いない。
evbarm/conf/APCに一行加えてやってみる。
mountroot: trying msdos...
mountroot: trying ffs...
root file system type: ffs
configure3
inittodr
WARNING: no TOD clock present
WARNING: using filesystem time
WARNING: CHECK AND RESET THE DATE!
uvm_swap_init
VOP_OPEN: vp=c1bf2dc0, vp->v_op=c1a35d28, VOFFSET(vop_open)=00000005
spec_open: start
cdevsw_lookup: dev=00000100, cmajor = 1, cdevsw = c01e0350
spec_open: cdev_type(dev) != D_DISK error=0
VOP_OPEN: error=0
uvm_scheduler
init: copying out flags `-s' 3
init: copying out path `/sbin/init' 11
move out arg pinters
sys_execve
VOP_OPEN: vp=c1bf2b00, vp->v_op=c1a35b68, VOFFSET(vop_open)=00000005
VOP_OPEN: error=0
sys_execve: error = -2
vn_open: pathstring=/dev/console
VOP_OPEN: vp=c1bf2c60, vp->v_op=c1a35a88, VOFFSET(vop_open)=00000005
spec_open: start
spec_open: VCHR
cdevsw_lookup: dev=00000200, cmajor = 2, cdevsw = c01e0350
cdevsw_lookup: dev=00000200, cmajor = 2, cdevsw = c01e0350
cdevsw_lookup: dev=00000200, cmajor = 2, cdevsw = c01e0350
cdev_open: d->d_open = c001034c, dev=00000200
cnopen: minor
cnopen: cn_tab == NULL?
cnopen: cndev=00007000
cnopen: cndev == NODEV?
cnopen: dev == cndev?
cnopen: cn_devvp == NULLVP? unit=0
cnopen: cdevvp()
cnopen: cdevvp() error=0
cnopen: vn_lock()
cnopen: vn_lock error=0
cnopen: VOP_OPEN cndevvp[0]=c1bf2a50
VOP_OPEN: vp=c1bf2a50, vp->v_op=c1a35d28, VOFFSET(vop_open)=00000005
spec_open: start
spec_open: VCHR
cdevsw_lookup: dev=00007000, cmajor = 112, cdevsw = c01e0350
cdevsw_lookup: dev=00007000, cmajor = 112, cdevsw = c01e0350
cdevsw_lookup: dev=00007000, cmajor = 112, cdevsw = c01e0350
cdev_open: d->d_open = c0184f7c, dev=00007000
panic: wmtcom: open

Stopped in pid 1.1 (init) at    netbsd:cpu_Debugger+0x4:        bx      r14
0xca86cbd4: netbsd:vpanic+0xc
0xca86cbec: netbsd:printf_nolog
0xca86cc0c: netbsd:wmtcomopen+0x14
0xca86cc34: netbsd:cdev_open+0x78
0xca86cc84: netbsd:spec_open+0x1b0
0xca86cca8: netbsd:VOP_OPEN+0xa0
0xca86ccd4: netbsd:cnopen+0x150
0xca86ccfc: netbsd:cdev_open+0x78
0xca86cd4c: netbsd:spec_open+0x1b0
0xca86cd70: netbsd:VOP_OPEN+0xa0
0xca86ce24: netbsd:vn_open+0x1e8
0xca86ce9c: netbsd:do_open+0xb0
0xca86cecc: netbsd:do_sys_openat+0x7c
0xca86cef0: netbsd:sys_open+0x34
0xca86cf84: netbsd:syscall+0x88
0xca86cfac: netbsd:swi_handler+0x98
db>
よし! wmt_com.cのwmtcomopenが呼ばれた!

ついに/sbin/initのシステムコールopenからソフトウェア割込み経由でカーネルに入り、vn_open -> spec_open -> cdev_open -> cn_open -> spec_open -> cdev_open -> wmtcomopenというopenの流れをつなぐことができた。

vnode(vn)からキャラクタデバイス(cdev)にいき、コンソール(cn)に行き、デバイスドライバに行き着くということなんだろうか。

gitリポジトリに久しぶりにcommit & push。ファイルをリネームして億劫になっていた。

結局、git mv oldfile newfileとやらねばならないらしく、ファイル名をいったん戻してからcommitし直して面倒だった。うかつに通常のmvを使ってはいけないね。

さて、ここまで来たら、またixp12x0_comを手本にしてシリアルコンソールドライバを作りこむことになりそうだ。

ハードウェア割込みとソフトウェア割り込みの合わせ技でread/writeするというのを実現しつつ、今のところ用途がわからない関数をうめていくのかなぁ。まずは、ユーザランドから一文字でもいいから出力してみたい。うん。

名前:  非公開コメント   

  • TB-URL  http://www.tokuda.net/diary/adiary.cgi/0839/tb/