免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 949 | 回复: 0
打印 上一主题 下一主题

网络设备的初始化 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-05-03 23:15 |只看该作者 |倒序浏览
网络设备的初始化
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}
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/66022/showart_665533.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP