linux网络设备驱动程序

4.linux网络设备驱动程序体系结构

     --------------------------------------
    |        数据包发送     |     数据包接收       |    ----->网络协议接口层
    |  dev_queue_xmit() |     netif_rx()       |
    |--------------------------------------
    |            结构体 net_device           |    ----->网络设备接 口层
     --------------------------------------
    |        数据包发送      |      中断处理       |    ----->网络驱动功能层
    |  hard_start_xmit() |     数据包接收       |
    |--------------------------------------
    |         网络设备媒介(物理层)           |    ----->网络设备与媒介层
     --------------------------------------

硬件相关的驱动程序(要提供hard_start_xmit, 有数据时要用netif_rx上报)

5.sk_buff套接字缓冲区,用于linux中各层之间传输数据。当要发送数据包的时候,内核必须建立一个包含传输数据的sk_buff
然后将sk_buff交给下层,各层在sk_buff递交给下一层,各层在sk_buff中添加不同的协议贞头,直到交给网络设备发送。接收原理相同。
struct sk_buff {
/* These two members must be first. */
struct sk_buff *next;
struct sk_buff *prev;
/*网络设备接口层中的net_devive结构体*/
struct net_device *dev;
....

/*控制缓冲区 ,每个层都可以使用它,用于存放私有数据*/
char cb[48];

unsigned int len, //数据真实长度
data_len,//数据长度
mac_len; //链接层帧头的长度
/*钩子函数 垃圾回收*/
void (*destructor)(struct sk_buff *skb);

sk_buff_data_t transport_header;
sk_buff_data_t network_header;
sk_buff_data_t mac_header;
/* These elements must be at the end, see alloc_skb() for details. */
sk_buff_data_t tail;
sk_buff_data_t end;
unsigned char *head,
*data;
unsigned int truesize;
atomic_t users;
};
5.1、sk_buff结构:
----------- ---->*head
| 头部 |
|------------ ---->*data
| 数据 |
| 缓存 |
|----------- ---->*tail
| 尾部 |
----------- ---->*end

5.2、分配:
分配套接字缓冲区:以GFP_ATOMIC优先级进行skb的分配,因为该函数经常在设备驱动中被调用
static inline struct sk_buff *dev_alloc_skb(unsigned int length)

分配一个套接字缓冲区和一个数据缓冲区,参数len为数据缓冲区的大小,ARM通常32位对齐,参数priority为内存分配的优先级。
static inline struct sk_buff *alloc_skb(unsigned int size,gfp_t priority)

5.3、释放:
//用于释放dev_alloc_skb的内存,用于非中断上下文中
void dev_kfree_skb(struct sk_buff *skb)
//用于中断上下文中
static inline void dev_kfree_skb_irq(struct sk_buff *skb)
//中断和非中断都可以用 any,其实就是做了一个判断
void dev_kfree_skb_any(struct sk_buff *skb)
{
if (in_irq() || irqs_disabled())
dev_kfree_skb_irq(skb);
else
dev_kfree_skb(skb);
}
5.4、变更:
缓冲区尾部增加数据 skb
static inline unsigned char *skb_put(struct sk_buff *skb, unsigned int len)
skb->tail += len;
skb->len += len;

缓冲区开头增加数据
static inline unsigned char *skb_push(struct sk_buff *skb, unsigned int len)
skb->data -= len;
skb->len += len;

缓冲区开头移除数据
static inline unsigned char *skb_pull(struct sk_buff *skb, unsigned int len)
skb->len -= len;
return skb->data += len;

调节缓冲区头部
static inline void skb_reserve(struct sk_buff *skb, int len)
skb->data += len;
skb->tail += len;

6.net_device结构体
struct net_device
{
/*网络设备名称*/
char name[IFNAMSIZ];

unsigned long mem_end; /* 共享内存结束地址 */
unsigned long mem_start; /* 共享内存开始地址 */
unsigned long base_addr; /* I/O设备的基地址 */
unsigned int irq; /* 设备中断号 */

unsigned char if_port; /* 多端口设备使用哪一个端口*/
unsigned char dma; /* DMA channel

/*设备初始化函数,只被调用一次 */
int (*init)(struct net_device *dev);

/*用于获取网络设备的状态信息*/
struct net_device_stats* (*get_stats)(struct net_device *dev);
/*存放详细的网络设备流量统计信息*/
struct net_device_stats stats;

.......................
unsigned mtu; /* interface MTU(最大传输单元) value*/
unsigned short type; /* 硬件接口类型 */
unsigned short hard_header_len; /* 硬件头的长度 */

/*MAC地址*/
unsigned char dev_addr[MAX_ADDR_LEN];

/*私有数据,用于存放私有的数据,netdev_priv()*/
void *priv;

/*启动数据包的发送*/
int (*hard_start_xmit) (struct sk_buff *skb,struct net_device *dev);

/*开始发送数据时候的时间戳 格式为:jiffies */
unsigned long trans_start;

/* 最后一次接受数据包的长度 */
unsigned long last_rx;

/* open用于打开网络设备,获取所需的IO地址和中断号.stop()用于停止网络设备 */
int (*open)(struct net_device *dev);
int (*stop)(struct net_device *dev);

/*用于设置设备的MAC地址*/
int (*set_mac_address)(struct net_device *dev,void *addr);

/*进行特定的IO控制*/
int (*do_ioctl)(struct net_device *dev,
struct ifreq *ifr, int cmd);
/*用于配置接口,可以用来改变设备的IO地址和中断号*/
int (*set_config)(struct net_device *dev,struct ifmap *map);

/*数据包发送超时时候会被调用,可以用来重启网卡*/
void (*tx_timeout) (struct net_device *dev);

/*linux4.0才有的一个结构体,linux2.6没有,操作硬件的集合*/
struct net_device_ops {
.....
};
};

时间: 2024-10-05 05:00:26

linux网络设备驱动程序的相关文章

Linux网络设备驱动结构概述

网络设备驱动相比字符型设备的驱动要复杂一些,除了总体上驱动的框架有一些相似外,有很多地方都是不同,但网络设备驱动有一个很大的特点就是有固定的框架可以遵循,具体的框架会在后边详细的叙述.1.网络协议接口层在网络协议接口层,只提供了两个抽象函数dev_queue_xmit()与 netif_rx(),之所以称之为抽象函数,是因为这两个函数抽象了很多底层的操作,不管是那个芯片它在网络协议结构的操作函数都是这两个函数,采用这样的抽象后,给上层带来了很多的方便,给上层协议提供统一的数据包收发接口,无论上层

Linux设备驱动程序(一)设备驱动程序简介

机制or策略: 驱动提供机制(what),而不是提供策略(how): 内核功能划分: 根据内核完成任务的不同,可分为如下几个部分: 1. 进程管理 负责进程的的创建和销毁,并处理它们和外部之间的连接(输入输出).不同进程之间的通信是整个系统的基本功能,因此由内核处理. 除此之外,控制进程如何共享CPU的调度器也是进程管理的一部分. 概括来说,内核进程管理就是在单个或者多个CPU上实现了多个进程的抽象. 2. 内存管理 内存是计算机的主要资源之一,用来管理内存的策略是决定系统性能的一个关键因素.

LINUX设备驱动程序笔记(一)设备驱动程序简介

<一>:设备驱动程序的作用 从一个角度看,设备驱动程序的作用在于提供机制,而不是策略.在编写驱动程序时,程序员应该特别注意下面这个基本概念:编写访问硬件的内核代码时,不要给用户强加任何特定策略.因为不同的用户有不同的需求,驱动程序应该处理如何使硬件可用的问题,而将怎样使用硬件的问题留给上层应用程序. 从另一个角度来看驱动程序,它还可以看作是应用程序和实际设备之间的一个软件层. 总的来说,驱动程序设计主要还是综合考虑下面三个方面的因素:提供给用户尽量多的选项.编写驱动程序要占用的时间以及尽量保持

Linux网络设备驱动(一) _驱动模型

Linux素来以其强大的网络功能著名,同时, 设备'>网络设备也作为三大设备之一, 成为Linux驱动学习中必不可少的设备类型, 此外, 由于历史原因, Linux并没有强制对设备'>网络设备贯彻其"一切皆文件"的思想, 设备'>网络设备不以/dev下的设备文件为接口,用户程序通过socket作为访问硬件的接口.本文以Linux3.14.0内核为例, 讨论Linux中的网络驱动模型 Linux的设备'>网络设备并不使用文件作为用户程序访问设备'>网络设备的

LINUX设备驱动程序笔记(一)设备驱动程序简单介绍

<一>:设备驱动程序的作用 从一个角度看,设备驱动程序的作用在于提供机制,而不是策略. 在编写驱动程序时,程序猿应该特别注意以下这个基本概念:编写訪问硬件的内核代码时,不要给用户强加不论什么特定策略.由于不同的用户有不同的需求,驱动程序应该处理如何使硬件可用的问题.而将如何使用硬件的问题留给上层应用程序. 从还有一个角度来看驱动程序.它还能够看作是应用程序和实际设备之间的一个软件层. 总的来说,驱动程序设计主要还是综合考虑以下三个方面的因素:提供给用户尽量多的选项.编写驱动程序要占用的时间以及

Linux 字符驱动程序(一)

Linux 字符驱动程序(一) 在linux内核中设备主要有三种: 1 字符设备: ?字符设备的读写以字节为单位,存取时没有缓存. ?对字符设备发出读写请求时,实际的硬件I/O紧接着就发生了.一般来说,字符设备不支持随机访问. ?典型的字符设备包括鼠标.键盘及串行口等. 2 块设备: ?块设备读写以块为单位,典型的块大小为512或1024字节. ?利用一块系统内存作为缓冲区,当用户进程对设备发出读写请求时,驱动程序先察看缓冲区中的内容,若缓冲区中的数据能满足用户的要求就返回相应的数据,否则就调用

Linux网络驱动程序

Linux 的网络系统主要是基于 BSD UNIX 的套接字机制.在系统与驱动程序之间定义了数据结构 sk_buff 进行数据传输.系统支持对发送数据和接收数据缓存,提供流控机制并提供对多协议的支持. 1. linux 网络驱动程序的体系结构 linux 网络驱动程序的体系结构从上到下分为4层,各层作用如下: (1)      网络协议接口层向网络层协议提供统一的数据包收发接口,不论上层是IP还是ARP,都通过 dev_queue_xmit 函数发送数据,并通过 net_rx 函数接收数据.这一

转:Linux网卡驱动程序编写

Linux网卡驱动程序编写 [摘自 LinuxAID] 工作需要写了我们公司一块网卡的Linux驱动程序.经历一个从无到有的过程,深感技术交流的重要.Linux作为挑战微软垄断的强有力武器,日益受到大家的喜爱.真希望她能在中国迅速成长.把程序文档贴出来,希望和大家探讨Linux技术和应用,促进Linux在中国的普及. Linux操作系统网络驱动程序编写 一.Linux系统设备驱动程序概述 1.1 Linux设备驱动程序分类 1.2 编写驱动程序的一些基本概念 二.Linux系统网络设备驱动程序

linux设备驱动程序该添加哪些头文件以及驱动常用头文件介绍(转)

原文链接:http://blog.chinaunix.net/uid-22609852-id-3506475.html 驱动常用头文件介绍 #include <linux/***.h> 是在linux-2.6.29/include/linux下面寻找源文件.#include <asm/***.h> 是在linux-2.6.29/arch/arm/include/asm下面寻找源文件.#include <mach/***.h> 是在linux-2.6.29/arch/ar