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) 并返回错误给调用者。

在这两个事件之间,指向 net_device_ops 的指针发生了变化,尽管在代码中除了初始化阶段之外没有任何地方明确地完成它。

内核版本为2.6.31.8,平台MIPS。用户空间和内核之间的通信通道是通过 netlink 套接字实现的。

任何人都可以建议可能出错的地方吗?感谢任何建议,谢谢。

标记

4

1 回答 1

0

“虫子在别处。”

第二台设备不应与现有设备交互。如果您register_netdev使用现有名称,则在检测到条件并返回ndo_init之前首先调用虚函数。-EEXIST也许你的 init 函数做了一些涉及一些全局变量的讨厌的事情。(例如,代码是否假设有一个设备,并在初始化期间存储一个指向它的全局指针?)

于 2012-10-14T20:54:19.133 回答