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 {
		.....
		};
	};
linux网络设备驱动程序的更多相关文章
- Linux网络设备驱动架构
		
Linux网络设备驱动程序体系结构分为四层:网络协议接口层.网络设备接口层.提供实际功能的设备驱动层以及网络设备与媒介层. (1)网络协议接口层向网络层协议提供统一的数据包收发接口,不论上层协议是AR ...
 - linux网络设备驱动
		
Linux网络设备驱动 Linux网络驱动程序的体系结构可划分为4个层次.Linux内核源代码中提供了网络设备接口及以网络子系统的上层的代码,移植特定网络硬件的驱动程序的主要工作就是完成设备驱动功能层 ...
 - Linux网络设备驱动架構學習(三)
		
Linux网络设备驱动架構學習(三) 接下來會從以下幾個方面介紹網絡設備驅動的編寫流程: 1.網絡設備的註冊與註銷 2.網絡設備的初始化 3.網絡設備的打開與釋放 4.網絡數據發送流程 5.網絡數據接 ...
 - Linux 字符驱动程序(一)
		
Linux 字符驱动程序(一) 于linux有三个主要的内核设备: 1 字符设备: •字符设备的读写以字节为单位,存取时没有缓存. •对字符设备发出读写请求时.实际的硬件I/ ...
 - Linux网络设备驱动架構學習(二)
		
Linux网络设备驱动架構學習(二) 接下來會從以下幾個方面介紹網絡設備驅動的編寫流程: 1.網絡設備的註冊與註銷 2.網絡設備的初始化 3.網絡設備的打開與釋放 4.網絡數據發送流程 5.網絡數據接 ...
 - 转:Linux网卡驱动程序编写
		
Linux网卡驱动程序编写 [摘自 LinuxAID] 工作需要写了我们公司一块网卡的Linux驱动程序.经历一个从无到有的过程,深感技术交流的重要.Linux作为挑战微软垄断的强有力武器,日益受到大 ...
 - linux网络设备理解
		
网络层次 linux网络设备驱动与字符设备和块设备有很大的不同. 1. 字符设备和块设备对应/dev下的一个设备文件.而网络设备不存在这样的设备文件.网络设备使用套接字socket访问,虽然也使用re ...
 - Linux网络驱动程序
		
Linux 的网络系统主要是基于 BSD UNIX 的套接字机制. 在系统与驱动程序之间定义了数据结构 sk_buff 进行传输数据.系统支持对发送数据和接收数据缓存,提供流控机制并提供对多协议的支持 ...
 - LINUX设备驱动程序笔记(一)设备驱动程序简单介绍
		
<一>:设备驱动程序的作用 从一个角度看,设备驱动程序的作用在于提供机制,而不是策略. 在编写驱动程序时,程序猿应该特别注意以下这个基本概念:编写訪问硬件的内核代码时,不要给用户强加不论什 ...
 
随机推荐
- ABP文档 - Mvc 视图
			
文档目录 本节内容: 简介 AbpWebViewPage 基类 简介 ABP通过nuget包Abp.Web.Mvc集成到Mvc视图里,你可以像往常那样创建常规的视图. AbpWebViewPage 基 ...
 - 趣说游戏AI开发:曼哈顿街角的A*算法
			
0x00 前言 请叫我标题党!请叫我标题党!请叫我标题党!因为下面的文字既不发生在美国曼哈顿,也不是一个讲述美国梦的故事.相反,这可能只是一篇没有那么枯燥的关于算法的文章.A星算法,这个在游戏寻路开发 ...
 - maven-sprigmvc-mybatis配置
			
pom.xml配置 <?xml version="1.0"?> <project xsi:schemaLocation="http://maven.ap ...
 - mac下生成ssh keys 并上传github仓储
			
使用github仓储需要本机生成一个公钥key 添加到自己的git账户SSH keys中 mac 生成方法: 1. 打开终端 输入 ssh-keygen 然后系统提示输入文件保存位置等信息 ...
 - #26 fibonacci seqs
			
Difficulty: Easy Topic: Fibonacci seqs Write a function which returns the first X fibonacci numbers. ...
 - ubuntu安装mysql
			
好记性不如烂笔头,记录一下,ubuntu安装mysql的指令. 安装MySQL: sudo apt-get install mysql-server sudo apt-get install mysq ...
 - .NET Core性能测试组件BenchmarkDotNet 支持.NET Framework Mono
			
.NET Core 超强性能测试组件BenchmarkDotNet 支持Full .NET Framework, .NET Core (RTM), Mono. BenchmarkDotNet支持 C# ...
 - 作为前端er,写在年末的一些话
			
写惯了技术类的文章,这种总结和唠嗑型的我基本也就在年末才来一篇.说实话,这种轻松类的文章往往比技术类的要受欢迎的多,因为其受众更广,看起来也不烧脑. 说来愧疚,这一年其实产出有点低,大致就写了不到二十 ...
 - vs 2015 "加载该页时出错。" 解决方案
			
错误信息: 加载该页时出错. 未找到与约束 ContractName Microsoft.CodeAnalysis.Editor.TypeScript.ScriptContexts.ITypeSc ...
 - 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock
			
ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...