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

2、注册网络设备

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

093e190faf13dec465fec543d25b0edc.gif

下面将结合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);0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Linux网络设备驱动代码例子: ```c #include <linux/module.h> #include <linux/init.h> #include <linux/netdevice.h> #define DRIVER_NAME "my_net_device" static struct net_device *net_dev; static int my_net_open(struct net_device *dev) { printk(KERN_INFO "my_net_device: device opened\n"); netif_start_queue(dev); return 0; } static int my_net_stop(struct net_device *dev) { printk(KERN_INFO "my_net_device: device stopped\n"); netif_stop_queue(dev); return 0; } static netdev_tx_t my_net_xmit(struct sk_buff *skb, struct net_device *dev) { printk(KERN_INFO "my_net_device: packet transmitted\n"); dev_kfree_skb(skb); return NETDEV_TX_OK; } static const struct net_device_ops my_net_dev_ops = { .ndo_open = my_net_open, .ndo_stop = my_net_stop, .ndo_start_xmit = my_net_xmit, }; static void my_net_setup(struct net_device *dev) { dev->netdev_ops = &my_net_dev_ops; } static int __init my_net_init(void) { net_dev = alloc_netdev(0, DRIVER_NAME, NET_NAME_UNKNOWN, my_net_setup); if (!net_dev) { printk(KERN_ERR "my_net_device: failed to allocate net device\n"); return -ENOMEM; } register_netdev(net_dev); printk(KERN_INFO "my_net_device: driver loaded\n"); return 0; } static void __exit my_net_exit(void) { unregister_netdev(net_dev); free_netdev(net_dev); printk(KERN_INFO "my_net_device: driver unloaded\n"); } module_init(my_net_init); module_exit(my_net_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name <your.email@example.com>"); MODULE_DESCRIPTION("My network device driver"); ``` 这个驱动程序创建了一个名为“my_net_device”的网络设备,注册了三个函数(`my_net_open`、`my_net_stop` 和 `my_net_xmit`),并在驱动程序初始化时分配了网络设备。该驱动程序的主要功能是将传入的数据包释放,并在控制台输出相应的消息。注意,这只是一个简单的例子,实际的网络设备驱动程序可能需要更多的功能和复杂性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值