新闻中心

EEPW首页>嵌入式系统>设计应用> 嵌入式Linux网络驱动程序的开发及实现原理

嵌入式Linux网络驱动程序的开发及实现原理

作者: 时间:2009-12-29 来源:网络 收藏
2.2.2 主要的操作方法
int (*init)(struct net_device *dev); 设备初始化和向系统注册的函数,仅调用一次;
int (*open)(struct net_device *dev);设备打开接口函数,当用ifconfig激活设备时被调用,注册所用的系统资源(I/O端口,IRQ,DMA等)同时激活硬件并增加使用计数;
int (*stop)(struct net_device *dev);执行open方法的反操作;
*hard_start_xmit;初始化数据包传输的函数;
*hard_header;该函数(在hard_start_xmit前被调用)根据先前检索到的源和目标硬件地址建立硬件头。 eth_header是以太网类型接口的默认函数;
2.3的编写及
系统各个层次之间的数据传送都是通过套接字缓冲区sk_buff完成的,sk_buff数据结构是各层协议数据处理的对象。sk_buff 与网络之间交换数据的媒介,向网络发送数据时,必须从其中获取数据源和数据长度;驱动程序从网络上接收到数据后也要将数据保存到sk_buff中才能交给上层协议处理。
对于实际以太网驱动程序,可以参照内核源码树中的相应模板程序,重点理解网络驱动的和程序的结构框架,然后针对的特定硬件改写代码,相应的操作函数。下面结合作者利用2.6.18内核在深圳优龙公司的FS2410板(SAMSUNG S3C2410处理器)上移植编写CS8900A网卡驱动程序的实例,说明网络驱动程序的实现
2.3.1网络设备初始化
网络设备的初始化是由net_device结构中的init函数实现的,内核加载网络驱动模块后,就会调用初始化过程。实例中初始化函数_init cs8900_probe中主要完成的工作:
a.调用内核中通用的设置以太网接口的函数ether_setup();
b.填充net_device结构体变量dev中其它大部分成员;
c.调用check_mem_region()检测I/O地址空间,然后调用request_mem_region()申请以dev->base_addr为起始地址的16个连续的 I/O地址空间;
d.通过cs8900_read()探测网卡CS8900A,读取ID信息;
e.设置CS8900A的INTRQ0作为中断信号输出引脚;
f.将MAC地址写入CS8900A的IA寄存器中;
g.通过register_netdev()将CS8900A注册到全局网络设备链表中;
2.3.2打开(或关闭)网络设备
系统响应ifconfig命令时,打开(关闭)一个网络接口。ifconfig命令开始会调用ioctl(SIOCSIFADDR)来将地址赋予接口。响应SIOCSIFADDR由内核来完成,与设备无关。接着,ifconfig命令会调用ioctl(SIOCSIFFLAGS)设置dev->flag的IFF_UP位来打开设备,这个调用会使设备的open方法得到调用。(当ifconfig调用ioctl(SIOCSIFFLAGS)清除dev->flag的IFF_UP位时,设备的stop方法将被调用)
实例中利用cs8900_start()函数打开网络设备,主要完成的工作:
a.通过set_irq_type()向内核注册网络设备的中断处理程序;
b.通过cs8900_set()设置CS8900A网卡中各控制寄存器和配置寄存器;
c.通过内核中netif_start_queue()函数开启网络接口的数据传输队列;
2.3.3网络数据包的发送
数据包的发送和接收是网络驱动程序中实现的两个最重要的任务。当网络设备被激活时,net_device结构中的open方法被调用,它负责打开设备并调用net_device结构中的hard_header函数指针建立硬件帧头信息。最后通过函数dev_queue_xmit() 来调用net_device结构中的hard_start_xmit方法把存放在sk_buff中的数据发送到网络物理设备。如果发送成功,则在hard_start_xmit中释放sk_buff并返回0;如果硬件设备忙暂时无法处理,则返回1。网络硬件在发送完数据包后会产生中断,把dev->tbusy置0,通知系统可以再次发送。
实例中,hard_start_xmit方法即为网络设备数据发送函数cs8900_send_start(),该函数实现把数据发送到以太网上,由网络协议接口层函数dev_queue_xmit()对其调用。cs8900_send_start()中主要完成的工作:
a.发送数据前关闭中断,中止网络设备的数据传输队列;
b.向CS8900A寄存器TxCMD中写入传送数据命令控制字,向寄存器TxLength中写入待发送数据帧长度;
c.通过cs8900_read()反复读取CS8900A总线状态寄存器BusST信息,直到其已经准备好接收来自主机的数据;
d.调用cs8900_frame_write()将待发数据送入CS8900A的sk_buff中,硬件设备会将数据帧发送到以太网上;
e.记录数据帧的发送时刻,打开中断,释放sk_buff缓存,函数返回0;
linux操作系统文章专题:linux操作系统详解(linux不再难懂)


评论


相关推荐

技术专区

关闭