网卡驱动1:linux网卡驱动重要数据结构——struct device

linux网卡驱动
 看了下linux的网卡驱动。
 linux驱动分为3种:1,字符设备;2,块设备;3,网络设备
 网络设备和其他两种设备的区别:
 (1)、网络接口不存在于 Linux 的文件系统中,而是在核心中用一个 device数据结构表示的。
 (2)、网络接口是在系统初始化时实时生成的,对于核心支持的但不存在的物理网络设备,将不可能有与之相对应的 device 结构
 

重要数据结构——struct device
 
/* from include/linux/netdevice.h */
 struct device
{
 (1)、属性
 char *name;
 设备的名字。如果第一字符为 NULL(即’/0’),register_netdev (drivers/net/net_init.c)将
 会赋给它一个 n 最小的可用网络设备名 ethn。
 
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 */
 这些域段标识被设备使用的共享内存的首地址及尾地址。如果设备用来接收和发送的内
 存块不同,则 mem 域段用来标识发送的内存位置,rmem 用来标识接收的内存位置。
 mem_start 和 mem_end 可在系统启动时用内核的命令行指定,用 ifconfig 可以查看它们
 的值。rmem 域段从来不被驱动程序以外的程序所引用。
 
unsigned long base_addr; /* device I/O address */
 unsigned char irq; /* device IRQ number */
 I/O基地址和中断号。它们都是在设备检测期间被赋值的,但也可以在系统启动时指定
 传入(如传给 LILO)。ifconfig 命令可显示及修改他们的当前值。
 
volatile unsigned char start; /* start an operation */
 volatile unsigned char interrupt; /* interrupt arrived */
 这是两个二值的低层状态标志。通常在设备打开时置 start 标志,在设备关闭时清 start
 标志。当 interrupt 置位时,表示有一个中断已到达且正在进行中断服务程序理。
 
unsigned long tbusy; /* transmitter busy must be long for bitops */
 标识“发送忙”。在驱动程序不能接受一个新的需传输的包时,该域段应该为非零。

struct device *next;
 指向下一个网络设备,用于维护链表。
 
unsigned char if_port;
 记录哪个硬件 I/O端口正在被接口所用,如 BNC, AUI, TP等(drivers/net/de4x5.h)。
unsigned char dma;
 设备用的 DMA通道。
 一些设备可能需要以上两个域段,但非必需的。
 
unsigned long trans_start; /* Time (in jiffies) of last Tx */
 上次传输的时间点(in jiffies)
 unsigned long last_rx; /* Time of last Rx */
 上次接收的时间点(in jiffies)。如trans_start 可用来帮助内核检测数据传输的死锁
 (lockup)。
 
unsigned short flags; /* interface flags (a la BSD) */
 该域描述了网络设备的能力和特性。它包括以下 flags:(include/linux/if.h)
 IFF_UP
表示接口在运行中。当接口被激活时,内核将置该标志位。
 IFF_BROADCAST
表示设备中的广播地址时有效的。以太网支持广播。
 IFF_DEBUG
调试模式,表示设备调试打开。当想控制 printk 及其他一些基于调试目的的信息显
 示时,可利用这个标志位。虽然当前没有正式的驱动程序使用它,但它可以在程序
 中通过 ioctl来设置从而使用它。
 IFF_LOOPBACK
表示这是一个回送(loopback)设备,回送接口应该置该标志位。核心是通过检查
 此标志位来判断设备是否是回送设备的,而不是看设备的名字是否是 lo。
 IFF_POINTTOPOINT
表示这是一个点对点链接(SLIP and PPP),点对点接口必须置该标志位。Ifconfig
 也可以置此标志位及清除它。若置上该标志位,则 dev->dstaddr应也相应的置为链
 接对方的地址。
 IFF_MASTER /* master of a load balancer */
 IFF_SLAVE /* slave of a load balancer */
 此两个标志位在装入平等化中要用到。
 IFF_NOARP
表示不支持ARP协议。通常的网络接口能传输ARP包,如果想让接口不执行ARP,
 可置上该标志位。如点对点接口不需要运行 ARP。
 IFF_PROMISC
全局接受模式。在该模式下,设备将接受所有的包,而不关这些包是发给谁的。在
 缺省情况下,以太网接口会使用硬件过滤,以保证只接受广播包及发给本网络接口
 的包。Sniff 的原理就是通过设置网络接口为全局接受模式,接受所有到达本接口
 媒介的包,来“偷听”本子网的“秘密”。
 IFF_MULTICAST
能接收多点传送的 IP包,具有多点传输的能力。ether_setup缺省是置该标志位的,
 故若不想支持多点传送,必须在初始化时清除该标志位。
 IFF_ALLMULTI
接收所有多点传送的 IP包。
 IFF_NOTRAILERS /*无网络 TRAILER*/
 IFF_RUNNING /*资源被分配*/
 此标志在 Linux 中没什么用,只是为了与 BSD兼容。
 unsigned short family; /* address family ID (AF_INET) */
 该域段标识本设备支持的协议地址簇。大部分为 AF_INET(英特网 IP 协议),接口通
 常不需要用这个域段或赋值给它。
 
unsigned short metric; /* routing metric (not used) */
 unsigned short mtu;
不包括数据链路层帧首帧尾的最大传输单位(Maximum Transfer Unit)。网络层在包传
 输时要用到。对以太网而言,该域段为 1500,不包括 MAC帧的帧首和帧尾(MAC帧
 格式稍后所示)。
 
unsigned short type; /* interface hardware type */
 接口的硬件类型,描述了与该网络接口绑在一起的媒介类型。Linux 网络设备支持
 许多不同种类的媒介,如以太网,X.25,令牌环,SLIP,PPP,Apple Localtalk 等。ARP
 在判定接口支持哪种类型的物理地址时要用到该域段。若是以太网接口,则在
 ether_setup中将之设为 ARPHRD_ETHER(Ethernet 10Mbps)。
 
unsigned short hard_header_len; /* hardware hdr length */
 在被传送的包中 IP头之前的字节数。对于以太网接口,该域段为 14(ETH_HLEN,
 include/linux/if_ether.h),这个值可由 MAC 帧的格式得出:
 MAC 帧格式:
 目的地址(6字节)+ 源地址(6 字节)+ 数据长度(2 字节)+ 数据(46~~1500)+FCS
 
void *priv; /* pointer to private data */
 该指针指向私有数据,通常该数据结构中包括 struct enet_statistics。类似于 struct file的
 private_data 指针,但 priv 指针是在设备初始化时被分配内存空间的(而不是在设备打
 开时),因为该指针指向的内容包括设备接口的统计数据,而这些数据即使在接口卸下
 (down)时也应可以得到的,如用户通过 ifconfig 查看。
 
unsigned char pad; /* make dev_addr aligned to 8 bytes */
 unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
 广播地址由六个 0xff 构成,即表示 255.255.255.255。
 memset(dev->broadcast,0xFF, ETH_ALEN); (drivers/net/net_init.c)
 
unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */
 设备的物理地址。当包传送给驱动程序传输时,要用物理地址来产生正确的帧首。
 
unsigned char addr_len; /* hardware address length */
 物理地址的长度。以太网网卡的物理地址为 6字节(ETH_ALEN)。
 
unsigned long pa_addr; /* protocol address */
 unsigned long pa_brdaddr; /* protocol broadcast addr */
 unsigned long pa_mask; /* protocol netmask */
 该三个域段分别描述接口的协议地址、协议广播地址和协议的网络掩码。若 dev->family
 为 AF_INET,则它们即为 IP地址。这些域段可用 ifconfig 赋值。
 
unsigned short pa_alen; /* protocol address length */
 协议地址的长度。AF_INET 的为 4。
 
unsigned long pa_dstaddr; /* protocol P-P other side addr */
 点对点协议接口(如 SLIP、PPP)用这个域记录连接另一边的 IP值。
 
struct dev_mc_list *mc_list; /* Multicast mac addresses */
 int mc_count; /* Number of installed mcasts*/
 struct ip_mc_list *ip_mc_list; /* IP multicast filter chain */
 这三个域段用于处理多点传输。其中 mc_count表示 mc_list中的项目数。
 
__u32 tx_queue_len; /* Max frames per queue allowed */
 一个设备的传输队列能容纳的最大的帧数。对以太网,缺省为 100;而 plip 则为节省系
 统资源,仅设为 10。
 
/* For load balancing driver pair support */
 unsigned long pkt_queue; /* Packets queued */
 struct device *slave; /* Slave device */
 struct net_alias_info *alias_info; /* main dev alias info */
 struct net_alias *my_alias; /* alias devs */
 
struct sk_buff_head buffs[DEV_NUMBUFFS];
 指向网络接口缓冲区的指针。
 
/* 基本操作 */
 int (*init) (struct device *dev); /* Called only once. */
 int (*open) (struct device *dev);
 int (*stop) (struct device *dev);
 int (*hard_start_xmit) (struct sk_buff *skb, struct device *dev);
 
int (*hard_header) (struct sk_buff *skb, struct device *dev, unsigned short type,
void *daddr, void *saddr, unsigned len);
 
int (*rebuild_header)(void *eth, struct device *dev, unsigned long raddr, struct sk_buff
 *skb);
 
1、“模块初始化模式”的分析
 (a) 、概述
 insmod命令将调用相应模块的init_module() ,装载模块。init_module函数在初始化dev->init函数指针后,将调用register_netdev()在系统登记该设备。若登记成功,则模块装载成功,否则返回出错信息。register_netdev首先检查设备名是否已确定,若没赋值则给它一个缺省的值ethN,N为最小的可用以太网设备号 注;然后,网络设备自己init_function,即刚在init_module中赋值的dev->init,将被调用,用来实现对网络接口的实际的初始化工作。若初始化成功,则将该网络接口加到网络设备管理表dev_base的尾部。整个函数调用关系图如下所示。下面我们以用得最广泛以太网卡之一——NE2000 兼容网卡为例子进行分析。NE2000网卡的主要驱动程序在文件drivers/net/ne.c中。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值