深入理解Linux网络技术内幕——设备的注册与初始化(二)
设备注册于设备除名
切割操作:netdev_run_todo
void rtnl_unlock(void) { /* This fellow will unlock it for us. */ netdev_run_todo(); } EXPORT_SYMBOL(rtnl_unlock);
设备注册状态通知
//格式: #define NETDEV_UP 0x0001 /* For now you can't veto a device up/down */ #define NETDEV_DOWN 0x0002 ...... //含义: NETDEV_UP //该报告表明设备被启用,由dev_open产生报告 NETDEV_DOWN //设备已关闭,由dev_close生成报告 NETDEV_REBOOT //因硬件设备,设备已重启 NETDEV_CHANGE //设备的状态或者配置发生改变 NETDEV_REGISTER //设备已经注册 NETDEV_UNREGISTER //设备已经除名 NETDEV_CHANGEMTU // NETDE // NETDEV_PRE_UP // NETDEV_PRE_TYPE_CHANGE // NETDEV_POST_TYPE_CHANGE // NETDEV_POST_INIT // NETDEV_UNREGISTER_FINAL // NETDEV_RELEASE // NETDEV_NOTIFY_PEERS // NETDEV_JOIN // NETDEV_CHANGEUPPER V_CHANGEADDR //设备硬件地址(或关联的广播地址)发生改变 NETDEV_GOING_DOWN // NETDEV_CHANGENAME //设备名称发生改变 NETDEV_FEAT_CHANGE // NETDEV_BONDING_FAILOVER // NETDEV_RESEND_IGMP //
设备注册:
int register_netdev(struct net_device *dev) { int err; rtnl_lock(); err = register_netdevice(dev); rtnl_unlock(); return err; }
- 初始化net_device的部分字段
- 如果内核支持Divert功能,则用alloc_divert_blk分配该功能所需的数据空间块,并连接至dev->divert
- 如果设备驱动已经对dev->init进行初始化,则执行此函数。
- 由dev_new_index分配给设备一个识别码。
- 把net_device插入到全局表dev_base,以及两张哈希表dev_name_head,dev_index_head。
- 检查功能标识是否有无效的组合。
- 设置dev->state中的__LINK_STATE_PRESENT标识,使得设备能为内核所用。
- 用dev_init_scheduler初始化设备队列规则,以便流量控制用于实现Qos。
- 通过netdev_chain通知表链通知所有对本设备注册感兴趣的子系统。
设备除名:
- 用dev_close关闭设备
- 释放所有分配的资源(IRQ、I/O端口...)
- 从全局表dev_base和两张哈希表中删除设备
- 当该设备的所有引用都释放后,释放net_device结构的空间、该驱动程序的私有数据结构、以及相链接的内存区域块。
- 删除添加到/proc 和/sys的所有文件
dev->stop //用以关闭设备,通常包括关闭netif_stop_queue出口,释放硬件资源等 dev->uninit //主要负责引用计数,少用到 dev->destructor //少数虚拟设备使用,通常初始化为: free_netdev 或其包裹函数
- 如果设备没关闭,使用dev_close关闭
- 从全局表dev_base和两张哈希表中删除设备
- 所有与该设备关联的队列规则实例,由dev_shutdown销毁
- 发送NETDEV_UNREGISTER消息到netdev_chain通知链。
- 除名消息也必须通知用户空间。
- 任何链接至net_device的数据块被释放
- register_netdevice中dev_init的所有操作都要有dev_uninit复原。
引用计数
网络设备的启用和关闭
//net/core/dev.c int dev_open(struct net_device *dev) static int __dev_open(struct net_device *dev)
- 如果 dev->open初始化了,就调用dev->open。
- 设置dev_state中的__LINK_STATE_START标识,以表明设备开启或在运行中
- 设置dev_flags中的IFF_UP,标识设备为开启。
- 调用dev_activate初始化流量控制所需使用到的出口队列规则,然后启用看门狗定时器。
- 向netdev_chain发送NETDEV_UP通知
- 向netdev_chain发送 NETDEV_GOING_DOWN通知
- 调用dev_deactivat关闭队列规则
- 清除dev->state的_ _LINK_STATE_START标志,以表明设备禁用了
- 如果正在执行读取入口队列数据包的轮询操作,则等待该操作完成。因为dev->state关系,入口队列不会再有入队操作,所以读取当前已经在队列中的即可
- 如果dev->stop有定义,执行它。
- 清除dev->flags的IFF_UP操作。
- 向netdev_chain发送NEtdEV_DOWN通知。
更新队列规则状态:
从用户空间配置设备相关信息
- ipconfig和mii-tool 来自net-tool套件
- ethtool 来自ethtool套件
- ip link:来自IP ROUTER2 套件
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。