08-网络设备的初始化
16.3 网络设备的初始化
网络设备的初始化主要需要完成如下几个方面的工作。
● 进行硬件上的准备工作,检查网络设备是否存在,如果存在,则检测设备所使用的硬件资源。
● 进行软件接口上的准备工作,分配net_device结构体并对其数据和函数指针成员赋值。
● 获得设备的私有信息指针并初始化其各成员的值。如果私有信息中包括自旋锁或信号量等并发或同步机制,则需对其进行初始化。
对net_device结构体成员及私有数据的赋值都可能需要与硬件初始化工作协同进行,即硬件检测出了相应的资源,需要根据检测结果填充net_device结构体成员和私有数据。
一个网络设备驱动初始化函数的模板如代码清单16.5所示,具体的设备驱动初始化函数并不一定完全和本模板一样,但是其本质过程是一致的。
代码清单16.5 网络设备驱动的初始化函数模板
1 void xxx_init(struct net_device *dev)
2 {
3 /设备的私有信息结构体/
4 struct xxx_priv *priv;
5
6 / 检查设备是否存在和设备所使用的硬件资源 /
7 xxx_hw_init();
8
9 / 初始化以太网设备的公用成员 /
10 ether_setup(dev);
11
12 /设置设备的成员函数指针/
13 dev->open = xxx_open;
14 dev->stop = xxx_release;
15 dev->set_config = xxx_config;
16 dev->hard_start_xmit = xxx_tx;
17 dev->do_ioctl = xxx_ioctl;
18 dev->get_stats = xxx_stats;
19 dev->change_mtu = xxx_change_mtu;
20 dev->rebuild_header = xxx_rebuild_header;
21 dev->hard_header = xxx_header;
22 dev->tx_timeout = xxx_tx_timeout;
23 dev->watchdog_timeo = timeout;
24
25 / 取得私有信息,并初始化它/
26 priv = netdev_priv(dev);
27 ... / 初始化设备私有数据区 /
28 }
上述代码第7行的xxx_hw_init()函数完成硬件相关的初始化操作如下。
● 探测xxx网络设备是否存在。探测的方法类似于数学上的“反证法”,即先假设存在设备xxx,访问该设备,如果设备的表现与预期的一致,就确定设备存在;否则,假设错误,设备xxx不存在。
● 探测设备的具体硬件配置。一些设备驱动编写得非常通用,对于同类的设备使用统一的驱动,我们需要在初始化时探测设备的具体型号。另外,即便是同一设备,在硬件上的配置也可能不一样,我们也可以探测设备所使用的硬件资源。
● 申请设备所需要的硬件资源,如用request_region()函数进行I/O端口的申请等,但是这个过程可以放在设备的打开函数xxx_open()中完成。