天天看点

linux dev alloc name,网络驱动移植之解析Linux网络驱动的基本框架

2、注册网络设备

通过register_netdev函数把已完成部分初始化的net_device结构体变量(即某个网络设备实例)注册到Linux内核中,大致过程如下图:

linux dev alloc name,网络驱动移植之解析Linux网络驱动的基本框架

下面将结合linux-2.6.38.8中的代码详细分析网络设备的注册过程。

(1)、获得rtnl信号量

rtnl_lock();

(2)、分配网络设备名(即%d对应的数字)

if(strchr(dev->name,'%')) {

err = dev_alloc_name(dev, dev->name);

if(err 

gotoout;

}

(3)、调用实际注册函数

err = register_netdevice(dev);

3.1、初始化dev->addr_list_lock自旋锁并根据dev->type设置其类别

spin_lock_init(&dev->addr_list_lock);

netdev_set_addr_lockdep_class(dev);

3.2、调用init函数

if(dev->netdev_ops->ndo_init) {

ret = dev->netdev_ops->ndo_init(dev);

if(ret) {

if(ret > 0)

ret = -EIO;

gotoout;

}

}

3.3、检测网络设备名是否有效

ret = dev_get_valid_name(dev, dev->name, 0);

if(ret)

gotoerr_uninit;

3.4、为网络设备分配唯一的索引号

dev->ifindex = dev_new_index(net);

if(dev->iflink == -1)

dev->iflink = dev->ifindex;

3.5、设置网络设备特性(dev->features)

if((dev->features & NETIF_F_HW_CSUM) &&

(dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {

printk(KERN_NOTICE"%s: mixed HW and IP checksum settings.\n",

dev->name);

dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM);

}

if((dev->features & NETIF_F_NO_CSUM) &&

(dev->features & (NETIF_F_HW_CSUM|NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {

printk(KERN_NOTICE"%s: mixed no checksumming and other settings.\n",

dev->name);

dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM);

}

dev->features = netdev_fix_features(dev->features, dev->name);

if(dev->features & NETIF_F_SG)

dev->features |= NETIF_F_GSO;

dev->vlan_features |= (NETIF_F_GRO | NETIF_F_HIGHDMA);

3.6、通过通知链告知内核其他子系统某种事件的发生(如注册网络设备)

ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev);

ret = notifier_to_errno(ret);

if(ret)

gotoerr_uninit;

ret = call_netdevice_notifiers(NETDEV_REGISTER, dev);

ret = notifier_to_errno(ret);

if(ret) {

rollback_registered(dev);

dev->reg_state = NETREG_UNREGISTERED;

}

3.7、创建网络设备在sysfs文件系统中的入口

ret = netdev_register_kobject(dev);

if(ret)

gotoerr_uninit;

3.8、设置网络设备为已注册状态

dev->reg_state = NETREG_REGISTERED;

3.9、设置网络设备状态为可用

set_bit(__LINK_STATE_PRESENT, &dev->state);

3.10、初始化网络设备的队列规则

dev_init_scheduler(dev);

3.11、获得网络设备的引用计数

dev_hold(dev);

3.12、加入到设备链表(如dev->dev_list、dev->name_hlist、dev->index_hlist)

list_netdevice(dev);

linux dev alloc name,网络驱动移植之解析Linux网络驱动的基本框架
下一篇: 页面自适应