网络设备的初始化
linux/include/linux/init.h
linux/net/net_init.c //好像现在变为了net/core/dev.c
linux/include/linux/etherdevice.h
网络设备被初始化,当linux内核发现了一定类型的设备通过调用probe函数去搜索一个适合的硬件和一个相关的驱动。
只要一个匹配的被发现了,那么驱动指明的初始化函数被调用。这个函数是通常被表示为__devinit或者__init,这两个东西被定义在linux/include/linux/init.h,当一个网络设备的驱动初始化函数或者probe函数被调用,第一件要做的就是申请驱动的私有化数据结构,这里的私有化数据结构包含了通用的net_device结构体;然后,必须设置一些关键的部位,第一个就是名字,它将作为后面用于注册网络接口设备,name通常被设置为一个字符串,用于标识设备的类型,比如,以太网设备通常用eth。最后的一位必须是%d。然后,当设备注册的时候,这个格式化的字符串被一个数字0-99替换;这俩步初始化至少可以用三种方式完成。非以太网设备可以在驱动的probe函数调用的时候去调用kmalloc去申请数据结构,通过dev_alloc_name去设置name字符串,然后直接初始化其他的设备特别的域(net_device 数据结构中的)。
linux提供了一些通用的设备申请和初始化函数,使得网络设备驱动的开发者可以比较方便进行开发,大部分这些可以在linux/net/net_init.c(我并没有再找到这个文件了)中,除了一些诶函数是为了特殊的以太网设备的,比如,我们将会看到以太网设备的初始化过程,这个过程使用了一个申请函数提供给了以太网设备驱动,这个函数alloc_etherdev(变成了一个宏了),这个函数定义在drivers/net/net_init.c和在文件linux/include/linux/etherdevice.h。数据结构的申请和初始化都被做了。在alloc_etherdev调用alloc_netdev,1* 传递一个指向setup函数的指针当作第二个参数,这个函数通常是ether_setup在早一些的内核版本中。函数netdev_boot_setup,实际是保存了所有boot time的设置杂一个netdev_boot_setup数据结构中,然后,这些设置被装入net_device数据结构中通过调用netdev_boot_setup_check.
当初始化到这一步时,net_device结构题被初始化:name,irq,base address,和io映射的范围。对于大多数的设备来说,更多的设备需要更多的数据被初始化在注册以前。硬件中断必须被设置,和任何的设备特殊的信息从设备中读出来,同时pci 配置空间,在这些结束后,初始化函数建立了自旋锁和其他的硬件特殊的信息,如果这些步骤不产生错误,那么priv被设置为指回到私有的数据结构,这些缓存被申请用来传输和接受从dma中。然后,指向这个驱动的服务函数被设置在net_device结构题中。最重要的服务例程是open,hard_start,stop,get_stats,set_multicast_list,和do_ioctl。然后一些特性将被填充去暗示设备的能力,比如计算ip校验和的功能。
1*
struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count)
{
return alloc_netdev_mq(sizeof_priv, "eth%d", ether_setup, queue_count);
}
EXPORT_SYMBOL(alloc_etherdev_mq);
下面是一个实例:
/**
147 * el1_probe: - probe for a 3c501
148 * @dev: The device structure passed in to probe.
149 *
150 * This can be called from two places. The network layer will probe using
151 * a device structure passed in with the probe information completed. For a
152 * modular driver we use #init_module to fill in our own structure and probe
153 * for it.
154 *
155 * Returns 0 on success. ENXIO if asked not to probe and ENODEV if asked to
156 * probe and failing to find anything.
157 */
158
159struct net_device * __init el1_probe(int unit)
160{
161 struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
162 static unsigned ports[] = { 0x280, 0x300, 0};
163 unsigned *port;
164 int err = 0;
165
166 if (!dev)
167 return ERR_PTR(-ENOMEM);
168
169 if (unit >= 0) {
170 sprintf(dev->name, "eth%d", unit);
171 netdev_boot_setup_check(dev);
172 io = dev->base_addr;
173 irq = dev->irq;
174 mem_start = dev->mem_start & 7;
175 }
176
177 SET_MODULE_OWNER(dev);
178
179 if (io > 0x1ff) { /* Check a single specified location. */
180 err = el1_probe1(dev, io);
181 } else if (io != 0) {
182 err = -ENXIO; /* Don't probe at all. */
183 } else {
184 for (port = ports; *port && el1_probe1(dev, *port); port++)
185 ;
186 if (!*port)
187 err = -ENODEV;
188 }
189 if (err)
190 goto out;
191 err = register_netdev(dev);
192 if (err)
193 goto out1;
194 return dev;
195out1:
196 release_region(dev->base_addr, EL1_IO_EXTENT);
197out:
198 free_netdev(dev);
199 return ERR_PTR(err);
200}
阅读(1588) | 评论(0) | 转发(0) |