深入理解Linux网络技术内幕学习笔记第八章:设备注册和初始化

在第五章和第六章,讨论了内核如何验证NIC以及内核所做的初始化,使得NIC得以和设备驱动程序对话。本章将讨论初始化的其他步骤。
设备注册和除名
注册时机:
    一,加载NIC设备驱动程序:若驱动内建在内核,则则在引导期间初始化,若以模块加载,则在允许期间初始化。初始化完成后,该驱动所控制的所有NIC都会被注册。
    二,插入可热插拔设备。可热插拔设备被插入时,内核会通知其驱动(假设相关驱动已加载),驱动再注册设备。
除名时机:
    卸载NIC设备驱动,删除可热插拔设备。
分配net_device结构:
调用alloc_netdev(net/core/dev.c)来返回一个指向net_device结构的指针。该函数需要三个参数:
    私有数据的大小:net_device结构可以驱动扩充,即加速一个私有数据区。
    设备名称
    设置函数:用于初始化net_device的部分字段。
内核提供一组包裹函数来提供正确的参数给alloc_netdev。例如,alloc_etherdev用于Ethernet设备。
设备注册时,驱动程序调用适当的内含alloc_netdev的包裹函数来获取net_device数据结构。有些驱动还会调用netdev_boot_setup_check来检查加载内核时用户是否提供了任何引导期间参数,见第七章使用引导选项配置网络设备一节。最后,register_netdevice会将新的net_device实例插入设备数据库中。
register_netdevice负责一部分的注册,然后net_set_todo把新的net_device实例添加到一个列表,最后netdev_run_todo会浏览该列表完成net_device实例。
设备注册状态是提供两种方式传递的:
    netdev_chain:
    Netlink的RTMGRP_LINL多播群组:
设备初始化:
设备初始化可以理解为就是初始化net_device结构中的字段,这些字段会一批一批的由不同函数初始化。主要分为三部分:
    设备驱动程序初始化:由设被驱动程序所初始化的字段通常由第六章提到的xxx_probe函数负责,例如IRQ,I/O内存,I/O端口。
    设备类型初始化:对常见的网络设备,xxx_setup函数可以对net_device结构中同一系列设备的通用字段初始化。
    可选的初始化和特殊情况。
设备除名的主要步骤:
以dev_close关闭设备。
释放所有已分配的资源,如IRQ,I/O内存等。
从全局列表dev_base和两个hash表中把net_device结构删除。
一旦net_device的所有引用都释放了,就释放net_device结构。
删除添加到/proc和/sys的文件。
开启和关闭网络设备
设备注册后就可以使用了,但是需要用于明确开启,否则还是无法传输和接收数据。dev_open函数负责开启设备(net/core/dev.c)。设备开启主要做以下一些工作:
    调用net_device结构中的open函数(如果定义了的话)。
    设置net_device结构中的state字段为_ _LINK_STATE_START标识设备为开启和运行状态。
    设置net_device结构中的flags字段为IFF_UP标识设备为开启。
    调用dev_activate初始化由流量控制使用的出口队列规则,然后启动看门狗定时器。
    发送设备开启的通知信息给netdev_chain通知链。
关闭设备的流程和开启相反。
net_device结构中的state字段如何处理电源管理和链路变更:
电源管理:
当内核支持电源管理时,只要系统挂起或重新继续,NIC设备驱动程序就会收到通知。在第六章提到,pci_driver结构中有两个函数指针suspend和resume。当系统挂起时,就会执行设备驱动提供的suspend函数,并清除state字段中的_ _LINK_STATE_PRESENT,若设备已开启,还会关闭出口队列。当系统重新继续时,调用resume函数,然后设置 _ _LINK_STATE_PRESENT,若设备挂起前已开启,则打开其出口队列且重启流量控制所使用的看门狗定时器。
链路状态变更侦测:
可能导致链接状态变更的一些常见情况:
一,电缆插入NIC,或者从NIC拔出。
二,电缆线另一端的设备电源关闭了。这类设备有Hub,路由器,桥接器,以及PC NIC等
当设备驱动侦测到设备上有载波而调用netif_carrier_on时,此函数会:
清除state中的 _ _LINK_STATE_NOCARRIER标识。
产生一个链路状态变更事件,并交给linkwatch_fire_event处理。
若设备已开启,启动看门狗定时器,以侦测传输是否失败。
当设备驱动侦测到设上遗失载波而调用netif_carrier_off时,此函数会:
设置state中的 _ _LINK_STATE_NOCARRIER标识。
产生一个链路状态变更事件,并交给linkwatch_fire_event处理。
链路变更事件用lw_event结构定义。此结构只有两个字段,一个指向相关net__device的指针和一个用来构成全局lweventlist列表的指针。全局链表包含未决的链路变更事件。任何设备都只有一个lw_event实例在链表中。当设备已有一个未决链接状态变更事件时,新事件就不需要入队了,该情况可以用state中的 _ _LINK_STATE_LINKWATCH_PENDING标识判断。对lw_event实例的处理只包括三个方面:
    清除 state中的 _ _LINK_STATE_LINKWATCH_PENDING标识。
    发送相关通知信息到netdev_chain通知链。
    发送RTM_NEWLINK通知信息到RTMGRP_LINK RTnetlink群组。
从用户空间配置设备:
配置网络设备的一些工具:
ifconfig和mii-tool,来自net-tools套件。
ethtool,来自ethtool套件。
ip link,来自IPROUTE2套件。
虚拟设备:
Bonding:允许你绑定一组接口使其看起来像是一个接口,流量可以通过各种算法分散在这些接口之间,当eth0宕掉时,bond0在真实设备间分配流量时必须知道此事,把这件事考虑进来,若eth1也宕掉了,bond0就得关闭。
VLAN:Linux支持802.1Q协议,允许定义VLAN接口。如下图,当eth0宕掉时,所有虚拟接口也必须宕掉。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值