手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>网站运营>建站经验>列表

Linux网卡驱动程式

来源:互联网 作者:west263.com 时间:2008-04-16
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

PACKET_MULTICAST : 链路层组播
PACKET_SELF : 发给自己的帧
PACKET_OTHERHOST : 发给别人的帧(监听模式时会有这种帧)

最后调用netif_rx()把数据传送给协议层。netif_rx()里数据放入处理队列然后返
回,真正的处理是在中断返回以后,这样能够减少中断时间。调用netif_rx()以后,
驱动程式就不能再存取数据缓冲区skb。

2.2.6 硬件帧头(hard_header)
硬件一般都会在上层数据发送之前加上自己的硬件帧头,比如以太网(Ethernet)
就有14字节的帧头。这个帧头是加在上层ip、ipx等数据包的前面的。驱动程式提供
一个hard_header方法,协议层(ip、ipx、arp等)在发送数据之前会调用这段程式。
硬件帧头的长度必须填在dev->hard_header_len,这样协议层回在数据之前保留好
硬件帧头的空间。这样hard_header程式只要调用skb_push然后正确填入硬件帧头就
能够了。
在协议层调用hard_header时,传送的参数包括(2.0.xx):数据的sk_buff,
device指针,protocol,目的地址(daddr),源地址(saddr),数据长度(len)。数据
长度不要使用sk_buff中的参数,因为调用hard_header时数据可能还没完全组织好。
saddr是NULL的话是使用缺省地址(default)。daddr是NULL表明协议层不知道硬件目
的地址。假如hard_header完全填好了硬件帧头,则返回添加的字节数。假如硬件帧
头中的信息还不完全(比如daddr为NULL,但是帧头中需要目的硬件地址。典型的情
况是以太网需要地址解析(arp)),则返回负字节数。hard_header返回负数的情况
下,协议层会做进一步的build header的工作。现在Linux系统里就是做arp
(假如hard_header返回正,dev->arp=1,表明无需做arp,返回负,dev->arp=0,
做arp)。
对hard_header的调用在每个协议层的处理程式里。如ip_output。

2.2.7 地址解析(xarp)
有些网络有硬件地址(比如Ethernet),并且在发送硬件帧时需要知道目的硬件
地址。这样就需要上层协议地址(ip、ipx)和硬件地址的对应。这个对应是通过地址
解析完成的。需要做arp的的设备在发送之前会调用驱动程式的rebuild_header方
法。调用的主要参数包括指向硬件帧头的指针,协议层地址。假如驱动程式能够解
析硬件地址,就返回1,假如不能,返回0。
对rebuild_header的调用在net/core/dev.c的do_dev_queue_xmit()里。

2.2.8 参数配置和统计数据
在驱动程式里还提供一些方法供系统对设备的参数进行配置和读取信息。一般
只有终极用户(root)权限才能对设备参数进行配置。配置方法有:
dev->set_mac_address()
当用户调用ioctl类型为SIOCSIFHWADDR时是要配置这个设备的mac地址。一般
对mac地址的配置没有太大意义的。
dev->set_config()

------------------ Linux操作系统网络驱动程式编写 -------------------
------------ Contact the author by mailto:bordi@bordi.dhs.org ------

当用户调用ioctl时类型为SIOCSIFMAP时,系统会调用驱动程式的set_config
方法。用户会传递一个ifmap结构包含需要的I/O、中断等参数。
dev->do_ioctl()
假如用户调用ioctl时类型在SIOCDEVPRIVATE和SIOCDEVPRIVATE 15之间,系统
会调用驱动程式的这个方法。一般是配置设备的专用数据。
读取信息也是通过ioctl调用进行。除次之外驱动程式还能够提供一个
dev->get_stats方法,返回一个enet_statistics结构,包含发送接收的统计信息。
ioctl的处理在net/core/dev.c的dev_ioctl()和dev_ifsioc()里。


2.3 网络驱动程式中用到的数据结构
最重要的是网络设备的数据结构。定义在include/linux/netdevice.h里。他
的注释已足够详尽。
struct device
{

/*
* This is the first field of the "visible" part of this structure
* (i.e. as seen by users in the "Space.c" file). It is the name
* the interface.
*/
char *name;

/* I/O specific fields - FIXME: Merge these and struct ifmap into one */
unsigned long rmem_end; /* shmem "recv" end */
unsigned long rmem_start; /* shmem "recv" start */
unsigned long mem_end; /* shared mem end */
unsigned long mem_start; /* shared mem start */
unsigned long base_addr; /* device I/O address */
unsigned char irq; /* device IRQ number */

/* Low-level status flags. */
volatile unsigned char start, /* start an operation */
interrupt; /* interrupt arrived */
/* 在处理中断时interrupt设为1,处理完清0。 */
unsigned long tbusy; /* transmitter busy must be long
for
bitops */

struct device *next;

/* The device initialization function. Called only once. */
/* 指向驱动程式的初始化方法。 */
int (*init)(struct device *dev);

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!