mini2440网卡驱动 之 虚拟网卡@2.6.32注册netdev问题的解决

【mini2440网卡驱动 之 虚拟网卡@2.6.32注册netdev问题的解决】本文转自
在2.6.32内核里面,
register_netdev(dev)
-> register_netdevice(dev)
-> if(dev->netdev_ops->ndo_init)
之所一会出现null指针调用,因为本身dev下的netdev_ops都没有定义,值为NULL,当然不能调用ndo_init(NULL->ndo_init必然不存在)。所以解决办法是在vnet_init函数里面的register_netdev(vnet_dev之前加上)
vnet_dev->netdev_ops = & vnet_dev_ops;
并在上面定义
static struct net_device_ops vnet_dev_ops =
{
.ndo_open= vnet_open,//也可以不写
};
我这里顺便定义了一个
int vnet_open(struct net_device *dev)
{
printk("Open\n");

return 0;
}
当我再运行的时候发现设置IP后出现:



本以为问题解决了,但当我ifconfig查看的时候,却并没有发现vnet0网卡。用ifconfig vnet0 up命令也启动不了vnet0网卡。
再次查看内核代码,找不出问题。尝试先设置mac地址,果不其然,ifconfig vnet0 1.2.3.4后再ifconfig发现了vnet0。







简单的代码如下:

  1. #include
  2. #include
  3. #include

  4. static struct net_device *vnet_dev;
  5. int vnet_open(struct net_device *dev)
  6. {
  7. printk("Open\n");

  8. return 0;
  9. }
  10. static struct net_device_ops vnet_dev_ops =
  11. {
  12. .ndo_open= vnet_open,
  13. };
  14. static int vnet_init(void)
  15. {
  16. vnet_dev = alloc_netdev(0, "vnet%d", ether_setup);
  17. vnet_dev->dev_addr[0] = 0x11;
  18. vnet_dev->dev_addr[1] = 0x22;
  19. vnet_dev->dev_addr[2] = 0x33;
  20. vnet_dev->dev_addr[3] = 0x44;
  21. vnet_dev->dev_addr[4] = 0x55;
  22. vnet_dev->dev_addr[5] = 0x66;

  23. vnet_dev->netdev_ops = &vnet_dev_ops;

  24. register_netdev(vnet_dev);

  25. return 0;
  26. }
  27. static void vnet_exit(void)
  28. {
  29. unregister_netdev(vnet_dev);
  30. free_netdev(vnet_dev);

  31. return ;
  32. }
  33. module_init(vnet_init);
  34. module_exit(vnet_exit);
  35. MODULE_LICENSE("GPL");

看到还是有一部分人用的2.6.32内核,内核之间的差异还是有的,这个时候的变通就是真正考验我们的时候。最简单实用的方法就是结合内核错误栈打印的信息,到错误的函数里面加上printk函数,重新编译内核,慢慢调试,不管凭自己之力能否最终解决,至少应该去尝试。

    推荐阅读