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 {
.....
};
};

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

  1. Linux网络设备驱动架构

    Linux网络设备驱动程序体系结构分为四层:网络协议接口层.网络设备接口层.提供实际功能的设备驱动层以及网络设备与媒介层. (1)网络协议接口层向网络层协议提供统一的数据包收发接口,不论上层协议是AR ...

  2. linux网络设备驱动

    Linux网络设备驱动 Linux网络驱动程序的体系结构可划分为4个层次.Linux内核源代码中提供了网络设备接口及以网络子系统的上层的代码,移植特定网络硬件的驱动程序的主要工作就是完成设备驱动功能层 ...

  3. Linux网络设备驱动架構學習(三)

    Linux网络设备驱动架構學習(三) 接下來會從以下幾個方面介紹網絡設備驅動的編寫流程: 1.網絡設備的註冊與註銷 2.網絡設備的初始化 3.網絡設備的打開與釋放 4.網絡數據發送流程 5.網絡數據接 ...

  4. Linux 字符驱动程序(一)

    Linux 字符驱动程序(一) 于linux有三个主要的内核设备: 1 字符设备:         •字符设备的读写以字节为单位,存取时没有缓存.      •对字符设备发出读写请求时.实际的硬件I/ ...

  5. Linux网络设备驱动架構學習(二)

    Linux网络设备驱动架構學習(二) 接下來會從以下幾個方面介紹網絡設備驅動的編寫流程: 1.網絡設備的註冊與註銷 2.網絡設備的初始化 3.網絡設備的打開與釋放 4.網絡數據發送流程 5.網絡數據接 ...

  6. 转:Linux网卡驱动程序编写

    Linux网卡驱动程序编写 [摘自 LinuxAID] 工作需要写了我们公司一块网卡的Linux驱动程序.经历一个从无到有的过程,深感技术交流的重要.Linux作为挑战微软垄断的强有力武器,日益受到大 ...

  7. linux网络设备理解

    网络层次 linux网络设备驱动与字符设备和块设备有很大的不同. 1. 字符设备和块设备对应/dev下的一个设备文件.而网络设备不存在这样的设备文件.网络设备使用套接字socket访问,虽然也使用re ...

  8. Linux网络驱动程序

    Linux 的网络系统主要是基于 BSD UNIX 的套接字机制. 在系统与驱动程序之间定义了数据结构 sk_buff 进行传输数据.系统支持对发送数据和接收数据缓存,提供流控机制并提供对多协议的支持 ...

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

    <一>:设备驱动程序的作用 从一个角度看,设备驱动程序的作用在于提供机制,而不是策略. 在编写驱动程序时,程序猿应该特别注意以下这个基本概念:编写訪问硬件的内核代码时,不要给用户强加不论什 ...

随机推荐

  1. Android UI体验之全屏沉浸式透明状态栏效果

    前言: Android 4.4之后谷歌提供了沉浸式全屏体验, 在沉浸式全屏模式下, 状态栏. 虚拟按键动态隐藏, 应用可以使用完整的屏幕空间, 按照 Google 的说法, 给用户一种 身临其境 的体 ...

  2. 关于自己写C++的一点风格

    现在,我学了很长时间的C++,但是自己就是无法精通.许多知识是入门书上没有的.现在写C++最重要的就是风格问题. 我现在的C++风格: 把自己所有的东西都放在一个名称空间下. 没有全局的函数,有的函数 ...

  3. 基于ASP.NET/C#开发国外支付平台(Paypal)学习心得。

        最近一直在研究Paypal的支付平台,因为本人之前没有接触过接口这一块,新来一家公司比较不清楚流程就要求开发两个支付平台一个是支付宝(这边就不再这篇文章里面赘述了),但还是花了2-3天的时间通 ...

  4. java单向加密算法小结(2)--MD5哈希算法

    上一篇文章整理了Base64算法的相关知识,严格来说,Base64只能算是一种编码方式而非加密算法,这一篇要说的MD5,其实也不算是加密算法,而是一种哈希算法,即将目标文本转化为固定长度,不可逆的字符 ...

  5. css常用hack

    原文地址:css常用hack 突然想起今天早上在CNZZ看到的统计数据,使用IE6.7的用户比例还真多,看到之后我的心都碎了.微软都放弃了为毛还有这么多人不死心? 所以说,IE下的兼容还是得做的. – ...

  6. 走进缓存的世界(三) - Memcache

    系列文章 走进缓存的世界(一) - 开篇 走进缓存的世界(二) - 缓存设计 走进缓存的世界(三) - Memcache 简介 Memcache是一个高性能的分布式内存对象缓存系统,用于动态Web应用 ...

  7. java中Action层、Service层和Dao层的功能区分

    Action/Service/DAO简介: Action是管理业务(Service)调度和管理跳转的. Service是管理具体的功能的. Action只负责管理,而Service负责实施. DAO只 ...

  8. Spring配置文件标签报错:The prefix "XXX" for element "XXX:XXX" is not bound. .

    例如:The prefix "context" for element "context:annotation-config" is not bound. 这种 ...

  9. Cesium简介以及离线部署运行

    Cesium简介 cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎,一款开源3DGIS的js库.cesium支持3D,2D,2.5D形式的地图展示,可以自行绘制图形,高亮区 ...

  10. ABAP单元测试最佳实践

    本文包含了我在开发项目中经历过的实用的ABAP单元测试指导方针.我把它们安排成为问答的风格,欢迎任何人添加更多的Q&A's,以完成这个列表. 在我的项目中,只使用传统的ABAP report. ...