NIC注册和注销的通用架构
Linux系统中NIC网络设备驱动程序利用网络代码进行注册和注销有其通用的架构,这里以PCI Ethernet NIC为例,其他设备类型只是所以函数名称和调用方式不同,主要依据于设备总线提供的接口。
其中(a)为设备注册的大致流程图,而(b)为设备注销的流程图。
在PCI Ethernet NIC设备驱动程序的探测函数(热插拔设备)或模块初始化函数中,首先要为设备分配一个net_device数据结构,并对其中的成员进行必要的初始化,对其中与设备类型密切相关的特殊成员利用驱动程序自己实现的setup函数进行初始化;Ethernet NIC设备驱动程序还需要调用netdev_boot_setup_check检查是否在系统启动参数中对网络设备进行了设置;然后调用register_netdev完成设备的注册。
在分配net_device数据结构时,驱动程序一般不直接调用alloc_netdev函数,而是调用为其类型封装后的函数,如Ethernet NIC设备直接调用alloc_etherdev函数,使用更加方便简单。
而Ethernet NIC设备的注销则是相反的过程,首先调用unregister_netdev在系统中注销设备,然后将分配的net_device数据结构释放。
在释放net_device数据结构时,设备也可能不直接调用free_netdev函数中,而是调用net_device数据结构中的成员函数:
/* Called from unregister, can be used to call free_netdev */
void (*destructor)(struct net_device *dev);
虚拟设备驱动程序一般采用这种方式,实现自己的destructor函数来释放net_device数据结构。
系统初始化概括:
When the kernel boots up, it executesstart_kernel;which initializes a bunch of subsystems, as partiallyshown in Figure 5-1. Before start_kernel terminates, it invokes theinit kernel thread, which takes
care of the rest of the initializations. Most of the initialization activities related to this chapter happen to beinsidedo_basic_setup.
run_init_process determines the first process run on the system, the parent of all other processes; it has
a PID of 1 and never halts until the system is done;
在网络设备可以使用之前,一定要能够被内核所识别,而且要连接上正确的驱动程序;网络设备的注册,一部分是由内核来完成,一部分是由设备驱动程序来完成。
Hardware initialization
This is done by the device driver in cooperation with the generic bus layer (e.g., PCI or USB).configures such features of each device as the IRQ and I/O address so that they can interact with the kernel。
Software initialization
Before the device can be used, depending on what network protocols are enabled and configured, the
user may need to provide some other configuration parameters, such as IP addresses。
Each network device is represented in the Linux kernel by an instance of the net_device data structure在内核中,我们为每一个网络设备分配一个net_device的数据结构,来描述网络设备,这个数据结构的初始化由两个对象来完成,一个是相应的驱动设备,一个是内核。
设备和内核的交互通过两种方式:
Polling
Driven on the kernel side. The kernel checks the device status at regular intervals to see if it has
anything to say.
Interrupt
Driven on the device side. The device sends a hardware signal (by generating an interrupt) to the
kernel when it needs the kernel's attention.
一种是轮询,还有一种是中断。