[ARM笔记]设备驱动概述
2.2.3 网络设备驱动
本文引用地址:https://www.eepw.com.cn/article/201611/340660.htm网络设备和字符设备、块设备不同,Linux系统对其有专门的处理函数和机制。所有的Linux网络驱动程序都遵循通用的接口,设计时采用的是面向对象的方法。把所有网络设备都抽象为一个接口对象。由数据结构struct device来表示网络设备在内核中的运行情况,即网络设备接口,该结构提供了对所有网络设备的操作集合。它由以dev_base为头指针的设备链表来集中管理所有网络设备。该设备链表中的每个元素代表一个网络设备接口。数据结构device中有很多提供给系统访问和协议层调用的设备方法,包括提供给设备初始化和向系统注册用的init函数、打开和关闭网络设备的open和stop函数、处理数据包发送的函数hard_start_xmit,以及中断处理函数等。一般来讲,一个网络设备最基本的方法有初始化(initialize)、发送和接收。初始化,当把驱动程序载入系统的时候会调用此程序,主要完成检测设备、配置和初始化硬件、初始化device结构中的变量等。设备驱动各函数是网络设备接口层net_device数据结构的具体成员,它通过hard_start_xmit()函数启动发送操作,并通过网络设备上的中断触发接收操作。
Linux下编写网络设备驱动的主体工作是完成net_device结构体的填充以及成员函数的实现,底层最核心的工作是:发送数据包和接收数据包,接收数据包是由中断触发的。发送数据包函数的典型结构如下——网络设备驱动发送数据包的典型结构。
int xxx_tx(struct sk_buff *skb, struct net_device *dev)
{
int len;
char *data, shortpkt[ETH_ZLEN];
/* 获得有效数据指针和长度 */
data = skb->data;
len = skb->len;
if (len < ETH_ZLEN)
{
/* 如果帧长小于以太帧最小长度,补0 */
memset(shortpkt, 0, ETH_ZLEN);
memcpy(shortpkt, skb->data, skb->len);
len = ETH_ZLEN;
data = shortpkt;
}
dev->trans_start = jiffies; /* 记录发送时间戳 */
/* 设置硬件寄存器让硬件把数据包发送出去 */
xxx_hw_tx(data, len, dev);
//...
}
接收数据包的典型结构如下——网络设备驱动接受数据包的典型结构。
static void xxx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
//...
switch (status &ISQ_EVENT_MASK)
{
case ISQ_RECEIVER_EVENT:
/* 获取数据包 */
xxx_rx(dev);
break;
/* 其他类型的中断 */
}
}
static void xxx_rx(struct xxx_device *dev)
{
//...
length = get_rev_len (...);
/* 分配新的套接字缓冲区 */
skb = dev_alloc_skb(length + 2);
skb_reserve(skb, 2); /* 对齐 */
skb->dev = dev;
/* 读取硬件上接收到的数据 */
insw(ioaddr + RX_FRAME_PORT, skb_put(skb, length), length >> 1);
if (length &1)
skb->data[length - 1] = inw(ioaddr + RX_FRAME_PORT);
/* 获取上层协议类型 */
skb->protocol = eth_type_trans(skb, dev);
/*把数据包交给上层 */
netif_rx(skb);
/* 记录接收时间戳 */
dev->last_rx = jiffies;
//...
}
2.3 Linux设备文件的创建
Linux是一种类Unix系统,Unix的一个基本特点是“一切皆为文件”,它抽象了设备的处理,将所有的硬件设备都像普通文件一样看待,也就是说硬件可以跟普通文件一样打开、关闭和读写。系统中的设备都用一个特殊文件代表,叫做设备文件。在 Linux2.4以后的内核版本中引入了设备文件系统(devfs),所有的设备文件作为一个可以挂装的文件系统,这样就可以被文件系统进行统一管理,从而设备文件就可以挂装到任何需要的地方。
在前面也讲过,字符设备和块设备都可以通过文件节点来存取,而与字符设备和块设备不同,网络设备的访问是通过Socket而不是设备节点,在系统里根本就不存在网络设备节点,所以在此我们仅讨论块设备和字符设备。
那么如何在内核中创建设备文件的挂载节点呢?简单的说,设备文件是由系统调用创建的,在命令行中,mknod命令会调用同名的程序来创建文件节点。rename和unlink系统调用可以用于移动和删除节点,相应的命令是mv和rm。在使用cp命令时加上-R或-a参数,可以创建一个与原设备节点具有同样属性的节点。mknod命令,该命令形式如下:
#mknod [OPTION] NAME TYPE [MAJOR MINOR]
说明:option选项设置,最常用的就是-m,基本上可以不用;name自定义设备名称;type设备类型,有b和c还有p;MAJOR主设备号;MINOR次设备号。
mknod命令建立一个目录项和一个特殊文件的对应索引节点。第一个参数Name项是设备的名称,选择一个描述性的设备名称。
评论