0

私が取り組んでいるデバイスドライバーは、仮想デバイスを実装しています。ロジックは次のとおりです。

static struct net_device_ops virt_net_ops = {
  .ndo_init = virt_net_init,
  .ndo_open = virt_net_open,
  .ndo_stop = virt_net_stop,
  .ndo_do_ioctl = virt_net_ioctl,
  .ndo_get_stats    = virt_net_get_stats,
  .ndo_start_xmit   = virt_net_start_xmit,
};

...

  struct net_device *dev;
  struct my_dev *virt;

  dev = alloc_netdev(..);
  /* check for NULL */

  virt = netdev_priv(dev);

  dev->netdev_ops = &virt_net_ops;
  SET_ETHTOOL_OPS(dev, &virt_ethtool_ops);
  dev_net_set(dev, net);
  virt->magic = MY_VIRT_DEV_MAGIC;
  ret = register_netdev(dev);
  if (ret) {
     printk("register_netdev failed\n");
     free_netdev(dev);
     return ret;
  }
...

何が起こっているのかというと、どこかで'net_dev'のポインタnet_device_opsが破損しています。

1)デバイスを最初に作成し(net_devを割り当て、関数ポインターを含む静的構造で初期化されるnet_device_opsを含むフィールドを初期化します)、register_netdev()を呼び出すカーネルにデバイスを登録します-OK

2)同じ名前のデバイスの作成を再試行し、上記の手順を繰り返します。register_netdev()を呼び出すと、負の値が返され、free_netdev(dev)が呼び出され、呼び出し元にエラーが返されます。

そして、これら2つのイベントの間で、net_device_opsへのポインターが変更されましたが、コードのどこにも初期化フェーズを除いて明示的に実行されていません。

カーネルバージョンは2.6.31.8、プラットフォームMIPSです。ユーザースペースとカーネル間の通信チャネルは、ネットリンクソケットを介して実装されます。

誰かがおそらくうまくいかない可能性があることを提案できますか?アドバイスに感謝します、ありがとう。

マーク

4

1 に答える 1

0

「バグはどこかにあります。」

2番目のデバイスは、既存のデバイスと相互作用しないようにする必要があります。register_netdev既存の名前を使用している場合でも、条件が検出されて返さndo_initれる前に、仮想関数が最初に呼び出されます。-EEXISTたぶんあなたのinit関数はいくつかのグローバル変数を含む厄介なことをします。(たとえば、コードはデバイスが1つあると想定し、初期化中にそのデバイスへのグローバルポインターを隠しますか?)

于 2012-10-14T20:54:19.133 に答える