在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。
简单的代码如下:
-
#include
-
#include
-
#include
-
-
static struct net_device *vnet_dev;
-
int vnet_open(struct net_device *dev)
-
{
-
printk("Open\n");
-
-
return 0;
-
}
-
static struct net_device_ops vnet_dev_ops =
-
{
-
.ndo_open = vnet_open,
-
};
-
static int vnet_init(void)
-
{
-
vnet_dev = alloc_netdev(0, "vnet%d", ether_setup);
-
vnet_dev->dev_addr[0] = 0x11;
-
vnet_dev->dev_addr[1] = 0x22;
-
vnet_dev->dev_addr[2] = 0x33;
-
vnet_dev->dev_addr[3] = 0x44;
-
vnet_dev->dev_addr[4] = 0x55;
-
vnet_dev->dev_addr[5] = 0x66;
-
-
vnet_dev->netdev_ops = &vnet_dev_ops;
-
-
register_netdev(vnet_dev);
-
-
return 0;
-
}
-
static void vnet_exit(void)
-
{
-
unregister_netdev(vnet_dev);
-
free_netdev(vnet_dev);
-
-
return ;
-
}
-
module_init(vnet_init);
-
module_exit(vnet_exit);
-
MODULE_LICENSE("GPL");
看到还是有一部分人用的2.6.32内核,内核之间的差异还是有的,这个时候的变通就是真正考验我们的时候。最简单实用的方法就是结合内核错误栈打印的信息,到错误的函数里面加上printk函数,重新编译内核,慢慢调试,不管凭自己之力能否最终解决,至少应该去尝试。