本文共 2921 字,大约阅读时间需要 9 分钟。
2.1、网络设备的注册与注销
注册网络设备发生在下列情形: (1)加载网卡驱动程序 网卡驱动程序如果被编译进内核,则它在启动时被初始化,在运行时被作为模块加载。无论初始化是否发生,所以由驱动程序控制的网卡都被注册。 (2)插入可热拔插网络设备 当用户插入一块热拔插网卡,内核通知其对应的驱动程序以注册设备。(为了简单化,我们假定设备驱动程序已经被加载)。两个主要的情形会导致设备注销:(1)卸载网卡驱动程序 这只适用与驱动程序作为模块被加载的情形,当然不适于编译进内核的情况。当管理员卸载网卡设备驱动程序时,所有相关网卡的驱动程序都被注销。(2)移除热拔插网络设备 当用户从正在运行且内核支持热拔插功能的系统中移除热拔插网卡时,网络设备被注销。2.1.1、分配 net_device结构空间在内核中,网络设备由结构net_device表示,在注册网络设备之前,必须为之分配内存空间,这一任务由net/core/dev.c中定义的alloc_netdev函数来完成:内核也提供了一些封装alloc_netdev功能的函数,如下:
2.1.2、注册网络设备
网络设备注册(a)与注销模型(b):注:在这里,设备驱动初始化函数loopback_init并没有调用alloc_netdev来分配内存,而是直接调用kmalloc,实际上alloc_netdev只是对kmalloc的封装而已。
2.2、网络设备的方法2.2.1、打开与关闭设备打开网络设备一旦设备注册即可使用,但它必须在用户(或用户空间应用程序)使能后才可以收发数据。dev_open 处理设备使能的请求,它定义在net/core/dev.c,定义如下:打开设备由以下几部组成:
(1)如果 dev->open 被定义则调用它。并非所有的驱动程序都初始化这个函数。 (2)设置 dev->state 的__LINK_STATE_START 标志位,标记设备打开并在运行。(3)设置 dev->flags 的 IFF_UP 标志位标记设备启动。 (4)调用dev_activate所指函数初始化流量控制用的排队规则,并启动监视定时器。如果用户没有配置流量控制,则指定缺省的先进先出(FIFO)队列。 (5)发送 NETDEV_UP 通知给 netdev_chain 通知链以通知对设备使能有兴趣的内核组件。设备驱动的open方法来看看3com网卡的驱动drivers/net/3c59x.c中的vortex_open,它是在vortex_init()中(即驱动程序初始化的过程中)赋给dev->open函数指针:关闭网络设备
它由以下几步组成:
(1)发送 NETDEV_GOING_DOWN 通知到 netdev_chain 通知链以通知对设备禁止有兴趣的内核组件。 (2)调用 dev_deactivate 函数禁止出口队列规则,这样确保设备不再用于传输,并停止不再需要的监控定时器。 (3)清除 dev->state 标志的__LINK_STATE_START 标志位,标记设备卸载。 (4)如果轮询动作被调度在读设备入队列数据包,则等待此动作完成。这是由于__LINK_STATE_START 标志位被清除,不再接受其它轮询在设备上调度,但在标志被清除前已有一个轮询正被调度。 (5)如果 dev->stop 指针不空则调用它,并非所有的设备驱动都初始化此函数指针。 (6)清除 dev->flags 的 IFF_UP 标志位标识设备关闭。(7)发送 NETDEV_DOWN 通知给 netdev_chain 通知链,通知对设备禁止感兴趣的内核组件。2.2.2、传输数据与接收数据传输数据网络子系统中,数据最后由链路层协议调用dev_queue_xmit(),位于net/core/dev.c,完成传输,而dev_queue_xmit又会调用具体网络适配器的驱动程序方法dev->hard_start_xmit(),从而驱动网络适配器最终完成数据传输,参见vortex_start_xmit()。接收数据当网络适配器接收一个数据帧时,就会触发一个中断,在中断处理程序(位于设备驱动)中,会分配sk_buff数据结构保存数据帧,最后会调用netif_rx(),将套接字缓冲区放入网络设备的输入队列。对于3c39x.c,其过程如下:vortex_interrupt( )---> vortex_rx( )--->netif_rx( )。来看看回环设备的发送与接收过程:
转载地址:http://flqwm.baihongyu.com/