序的设计步骤,后面还结合具体实例来讲解。首先通过模块加载命令insmod来把网络设备驱动程序插入到内核之中。然后,insmod将调用init_module()函数首先对网络设备的init函数指针初始化,再通过调用register_netdev()函数在Linux系统中注册该网络设备。如果成功,再调用init函数指针所指的网络设备初始化函数来对设备初始化,将设备的device数据结构插入到dev_base链表的末尾。最后可以通过执行模块卸载命令rmmod,来调用网络驱动程序中的cleanup_module()函数,对网络驱动程序模块进行卸载。具体实现过程见图2所示。

通过模块初始化网络接口是在编译内核时标记为编译为模块。系统在启动时并不知道该接口的存在,需要用户在/etc/rc.d/目录中定义的初始启动脚本中写入命令或手动将模块插入内核空间来激活网络接口。这也给我们在何时加载网络设备驱动程序提供了灵活性。
应用实例
我们以NE2000兼容网卡为例,来具体介绍基于模块的网络驱动程序的设计过程。可以参考文件linux/drivers/net/ne.c和linux/drivers/net/8390.c。
1.模块加载和卸载
NE2000网卡的模块加载功能由init_module()函数完成。具体过程及解释如下:
int init_module(void) { int this_dev, found = 0; //循环检测ne2000类型的网络设备接口 for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { //获得网络接口对应的net-device结构指针 struct net_device *dev = &dev_ne[this_dev]; dev->irq = irq[this_dev]; //初始化该接口的中断请求号 dev->mem_end = bad[this_dev]; //初始化接收缓冲区的终点位置 dev->base_addr = io[this_dev]; //初始化网络接口的I/O基地址 dev-& |
|