1

FreeBSD 10.0 に新しい newbuf ドライバーをインストールしています。make でコンパイルすると、driver .ko ファイルが作成され、kldload で正常にロードできます。kldload は 0 を返し、kldstat 出力でデバイスを確認できます。/dev/** ファイルを開いてドライバを使用しようとすると、ファイルが存在しません。

この /dev/** ファイルは、device_attach メンバー メソッドにある make_dev 関数で作成する必要があると思います。kldload がこのアタッチ機能に到達したかどうかをテストします。ドライバーをデバッグするために printf と uprintf を書き込むと、コンソールにも dmesg の出力にも何も表示されません。しかし、問題は、device_identify および device_probe 関数の先頭 (ローカル変数定義の後) に printf を記述した後、コンソールでも dmesg でも出力が表示されないことです。

私の質問は、物理ドライバーに問題がある (見つからないなど) 場合でも、コースの開始時に kldload によって呼び出される device_identify メンバー関数で printf の出力を確認する必要があるということです (私は思います)。

newbuf ドライバーを printf でデバッグするときに間違いがありますか (hello_world デバイスドライバーも試しましたが、このドライバーでは dmesg で printf の出力を取得できます)。

主に、このドライバーの kldload プロセスをテスト/デバッグするにはどうすればよいですか?

ドライバー コードの一部の下 (少なくとも MSG1 が表示されるはずですが、表示されません):

struct mydrv_softc 
{
    device_t        dev;
};

static devclass_t mydrv_devclass;

static struct cdevsw mydrv_cdevsw = {
    .d_version  = D_VERSION,
    .d_name     = "mydrv",
    .d_flags    = D_NEEDGIANT,
    .d_open     = mydrv_open,  
    .d_close    = mydrv_close, 
    .d_ioctl    = mydrv_ioctl,
    .d_write    = mydrv_write,
    .d_read     = mydrv_read
};


static void mydrv_identify (driver_t *driver, device_t parent) {
    devclass_t dc;
    device_t child;

    printf("MSG1: The process inside the identfy function.");

    dc = devclass_find("mydrv");
    if (devclass_get_device(dc, 0) == NULL) {
        child = BUS_ADD_CHILD(parent, 0, "mydrv", -1);
    }
}

static int mydrv_probe(device_t dev) {
    printf("MSG2: The process inside the probe function.");
    mydrv_init();
    if (device_get_unit(dev) != 0)
        return (ENXIO);
    device_set_desc(dev, "FreeBSD Device Driver");
    return (0);
}

static int mydrv_attach(device_t dev) {
    struct mydrv_softc *sc;
    device_printf(dev, "MSG3: The process will make attachment.");
    sc = (struct mydrv_softc *) device_get_softc(dev);
    sc->dev = (device_t)make_dev(&mydrv_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644, "mydrv_drv");
    return 0;
}

static int mydrv_detach(device_t dev) {
        struct mydrv_softc *sc;
    sc = (struct mydrv_softc *) device_get_softc(dev);
        destroy_dev((struct cdev*)(sc->dev));
    bus_generic_detach(dev);
    return 0;
}

static device_method_t mydrv_methods[] = {
    DEVMETHOD(device_identify,  mydrv_identify),
    DEVMETHOD(device_probe,     mydrv_probe),
    DEVMETHOD(device_attach,    mydrv_attach),
    DEVMETHOD(device_detach,    mydrv_detach),
    { 0, 0 }
};

static driver_t mydrv_driver = {
    "mydrv",
    mydrv_methods,
    sizeof(struct mydrv_softc),
};

DRIVER_MODULE(mydrv, ppbus, mydrv_driver, mydrv_devclass, 0, 0);
4

2 に答える 2

0

コンソールに printf の出力が表示されない場合は、デバイス関数が呼び出されていない可能性があります。モジュールのコードを見せてもらえますか? DRIVER_MODULE() または DEV_MODULE() を使用しましたか? 利用している親子バスは?

于 2013-08-13T13:53:15.310 に答える
0

printfうまく動作すると思いますdevice_printfが、デバイス名も出力されるため、ログやdmesg出力を調べるときに簡単になるため、使用することを好みます。また、複数のデバッグ プリントを残し、システムのログ ファイルを確認してください。デバイス ドライバーのほとんどのログは、ログに記録され/var/log/messagesます。ただし、他のログ ファイルも確認してください。仮想マシンでコードを実行していますか? /devOS が仮想マシン上で実行されている場合、一部のデバイス ドライバーはデバイス ファイルを表示しません。デバイス ファイルを表示するには、おそらく実際のハードウェアで OS を実行する必要があります。私の知る限り、対応するデバイス ファイルが dmesg に見つからない場合、出力は dmesg に表示されません。/devしかし、私が述べたように、ログがうまくいくかもしれません。もちろん、デバッグする最も簡単な方法は、printf ステートメントを使用することです。これ以外に、別のシステムで実行されている gdb を使用してカーネルをデバッグできます。正確なプロセスには詳しくありませんが、これができることは知っています。ググってください。

于 2013-08-09T01:46:56.357 に答える