深入理解Linux网络技术内幕——设备的注册与初始化(二)
设备注册于设备除名
切割操作:netdev_run_todo
Netlink信号量的保护。这也是为什么register_netdev执行时需要请求锁,并且在返回时要释放锁的原因。一旦register_netdevice完成了它自己的工作,它会通过net_set_todo将net_device结构体添加到net_todo_list中。net_todo_list包含一系列有注册(或除名)操作需要被完成的设备列表。这份列表有register_netdev在释放锁时间接予以处理。
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 套件
深入理解Linux网络技术内幕——设备的注册与初始化(二)的更多相关文章
- 深入理解linux网络技术内幕读书笔记(五)--网络设备初始化
Table of Contents 1 简介 2 系统初始化概论 2.1 引导期间选项 2.2 中断和定时器 2.3 初始化函数 3 设备注册和初始化 3.1 硬件初始化 3.2 软件初始化 3.3 ...
- 深入理解linux网络技术内幕读书笔记(七)--组件初始化的内核基础架构
Table of Contents 1 引导期间的内核选项 2 注册关键字 3 模块初始化代码 引导期间的内核选项 linux运行用户把内核配置选项传给引导记录,然后引导记录再把选项传给内核. 在引导 ...
- 深入理解linux网络技术内幕读书笔记(三)--用户空间与内核的接口
Table of Contents 1 概论 1.1 procfs (/proc 文件系统) 1.1.1 编程接口 1.2 sysctl (/proc/sys目录) 1.2.1 编程接口 1.3 sy ...
- 深入理解Linux网络技术内幕——网络设备初始化
概述 内核的初始化过程过程中,与网络相关的工作如下所示: 内核引导时执行start_kernel,start_kernel结束之前会调用rest_init,rest_init初始化内核线 ...
- 深入理解linux网络技术内幕读书笔记(八)--设备注册与初始化
Table of Contents 1 设备注册之时 2 设备除名之时 3 分配net_device结构 4 NIC注册和除名架构 4.1 注册 4.2 除名 5 设备初始化 6 设备类型初始化: x ...
- 深入理解Linux网络技术内幕——PCI层和网络接口卡
概述 内核的PCI子系统(即PCI层)提供了不同设备一些通用的功能,以便简化各种设备驱动程序. PCI层重要结构体如下: pci_device_id 设备标识,根据PCI标志定 ...
- 《深入理解Linux网络技术内幕》阅读笔记 --- 路由基本概念
一.路由的基本概念 1.一条路由就是一组参数,这些参数存储了往一个给定目的地转发流量所需的信息,而一条路由所需的最少的参数集合为:(1)目的网络,(2)出口设备,(3)下一跳网关 2.路由中的相关术语 ...
- 深入理解linux网络技术内幕读书笔记(十)--帧的接收
Table of Contents 1 概述 1.1 帧接收的中断处理 2 设备的开启与关闭 3 队列 4 通知内核帧已接收:NAPI和netif_rx 4.1 NAPI简介 4.1.1 NAPI优点 ...
- 深入理解linux网络技术内幕读书笔记(九)--中断与网络驱动程序
Table of Contents 1 接收到帧时通知驱动程序 1.1 轮询 1.2 中断 2 中断处理程序 3 抢占功能 4 下半部函数 4.1 内核2.4版本以后的下半部函数: 引入软IRQ 5 ...
随机推荐
- [luogu 3957]跳房子
题目链接 50分做法 挺显然的一个做法,因为金币量是单调的(如果你花i枚金币可以得到最优解,i+1枚也一定可以),所以可以二分答案 然后对于二分出来的每个答案,都做一遍dp,效率$O(n^2logn) ...
- ovs-ofctl: s1 is not a bridge or a socket 解决方法
参考: ovs-vsctl: Error detected while setting up bridge ovs-ofctl: s1 is not a bridge or a socket 解决方法 ...
- javascript面向对象的一些写法
因为有闭包,能返回函数,所以针对于面向对象的封装,继承,多态三个特性实现,很舒服. 代码如下: <!DOCTYPE html> <html> <head> < ...
- BZOJ 3992 【SDOI2015】 序列统计
题目链接:序列统计 我来复习板子了……这道题也是我写的第一发求原根啊? 求原根方法: 从小到大依次枚举原根.设当前枚举的原根为\(x\),模数为\(p\),\(p-1\)的质因数分别为\(p_1,p_ ...
- hdu 5525 Product 数论算贡献
Product Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Proble ...
- MongoDB(课时16 分页显示)
3.4.2.11 数据分页显示 在MongoDB里面的数据分页显示也是符合于大数据要求的操作函数: skip(n):表示跨过多少数据行 limit(n):取出的数据行的个数限制 范例:分页显示(比如显 ...
- Python - PIL-pytesseract-tesseract验证码识别
N天前实现了简单的验证识别,这玩意以前都觉得是高大上的东西,一直没有去研究,这次花了点时间研究了一下,当然只是一些基础的东西,高深的我也不会,分享一下给大家吧. 关于python验证码识别库,网上主要 ...
- Windows 2008 更改网卡绑定顺序
用 ncpa.cpl 或者用鼠标右键点网上邻居进去也好. 来到网卡列表画面. 然后,你会发觉没有菜单去操作[高级设置], 这里,最高级的步骤来了, 就是你需要按一个 [Alt]把菜单给显示出来,太神奇 ...
- python-day65-django基础
一.MTV模型 1.官方说明: Django的MTV分别代表: Model(模型):负责业务对象与数据库的对象(ORM) Template(模版):负责如何把页面展示给用户 View(视图):负责业务 ...
- Andriod给textview文本关键字循环标亮加粗
在开发中,搜索到得关键字信息在展示时,通常需要标亮加粗,如下图(截取自蓝鲸医生助手搜索后的结果) 在文本中,关键字是“嘎”,所有“嘎”字都标亮加粗,标亮就是换种颜色.这里就要用到SpannableSt ...