net_device详解
网络设备接口层的主要功能是为千变万化的网络设备定义了统一,抽象的数据结构net_device结构体,以不变应万变,实现多种硬件在软件层次上的统一。每一个网络设备都由structnet_device来描述,该结构可使用如下内核函数进行动态分配
struct net_device*alloc_netdev(int sizeof_priv, const char *mask, void(*setup)(struct net_device*))
sizeof_priv是私有数据区大小;
mask是设备名,
setup是初始化函数,注册该设备时,该函数被调用。
struct net_device*alloc_etherdev(int sizeof_priv)
这个函数和上面的函数不同之处在于内核知道会将该设备做一个以太网设备看待并做一些相关的初始化。
网络设备注册方式与字符驱动不同在于它没有主次设备号,它使用下面的函数注册:
int register_netdev(structnet_deivce*dev)
网络设备的注销:
voidunregister_netdev(struct net_device*dev)
一、net_device结构体
net_device结构可分为全局成员、硬件相关成员、接口相关成员、设备方法成员和公用成员等五个部分
1、主要全局成员
charname[INFAMSIZ] 设备名,如:eth0
unsigned longstate 设备状态,
unsigned longbase_addr I/O基地址,
unsigned intirq 中断号。
2、主要设备方法有
首先看打开和关闭网络设备的函数:
int (*open)(struct net_device *dev);
打开接口,ifconfig激活时,接口将被打开ifconfig eth0 up 会调用这里的open函数。
int (*stop)(struct net_device *dev);
停止接口,ifconfig eth0 down 会调用这里的stop函数。
在使用ifconfig向接口赋予地址时,要执行两个任务。首先,它通过ioctl(SIOCSIFADDR)(SocketI/O Control Set Interface Address)赋予地址,然后通过ioctl(SIOCSIFFLAGS)(Socket I/O Control Set InterfaceFlags)设置dev->flag中的IFF_UP标志以打开接口。这个调用会使得设备的open方法得到调用。类似的,在接口关闭时,ifconfig使用ioctl(SIOCSIFFLAGS)来清理IFF_UP标志,然后调用stop函数。
int (*init)(struct net_device*dev)
初始化函数,该函数在register_netdev时被调用来完成对net_device结构的初始化
int (*hard_start_xmit)(structsk_buf*skb,struct net_device *dev)
数据发送函数
int (*hard_header)(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len);
该方法根据先前检索到的源和目的硬件地址建立硬件头
int (*rebuild_header)(struct sk_buff *skb);
以太网的mac地址是固定的,为了高效,第一个包去询问mac地址,得到对应的mac地址后就会作为cache把mac地址保存起来。以后每次发包不用询问了,直接把包的地址拷贝出来。
void (*tx_timeout)(struct net_device *dev);
如果数据包发送在超时时间内失败,这时该方法被调用,这个方法应该解决失败的问题,并重新开始发送数据。
struct net_device_stats *(*get_stats)(struct net_device *dev);
当应用程序需要获得接口的统计信息时,这个方法被调用。
int (*set_config)(struct net_device *dev, struct ifmap *map);
改变接口的配置,比如改变I/O端口和中断号等,现在的驱动程序通常无需该方法。
int (*do_ioctl)(struct net_device *dev, struct ifmap *map);
用来实现自定义的ioctl命令,如果不需要可以为NULL。
void (*set_multicast_list)(struct net_device *dev);
当设备的组播列表改变或设备标志改变时,该方法被调用。
int (*set_mac_address)(struct net_device *dev, void *addr);
如果接口支持mac地址改变,则可以实现该函数。
二、驱动的实现
net_device结构体的成员(属性和函数指针)需要被设备驱动功能层的具体数值和函数赋予。对具体的设置xxx,工程师应该编写设备驱动功能层的函数,这些函数型如xxx_open(),xxx_stop(),xxx_tx(),xxx_hard_header(),xxx_get_stats(),xxx_tx_timeout()等。
1、初始化(init)
设备探测工作在init方法中进行,一般调用一个称之为probe方法的函数初始化的主要工作时检测设备,配置和初始化硬件,最后向系统申请这些资源。此外填充该设备的dev结构,我们调用内核提供的ether_setup方法来设置一些以太网默认的设置。
2、打开(open)
open这个方法在网络设备驱动程序里是网络设备被激活时被调用(即设备状态由down变成up)实际上很多在初始化的工作可以放到这里来做。比如说资源的申请,硬件的激活。如果dev->open返回非0,则硬件状态还是down,
注册中断、DMA等;设置寄存器,启动设备;启动发送队列
一般注册中断都在init中做,但在网卡驱动程序中,注册中断大部分都是放在open中注册,因为要经常关闭和重启网卡
3、关闭(stop)
stop方法做和open相反的工作可以释放某些资源以减少系统负担stop是在设备状态由up转为down时被调用
4、发送(hard_start_xmit)
在系统调用的驱动程序的hard_start_xmit时,发送的数据放在一个sk_buff结构中。一般的驱动程序传给硬件发出去。也有一些特殊的设备比如说loopback把数据组成一个接收数据在传送给系统或者dummy设备直接丢弃数据。
如果发送成功, hard_start_xmit方法释放sk_buff。如果设备暂时无法处理,比如硬件忙,则返回1。
5、接收
驱动程序并存在一个接受方法。当有数据收到时驱动程序调用netif_rx函数将sk_buff交给设备无关层。一般设备收到数据后都会产生一个中断,在中断处理程序中驱动程序申请一块sk_buff(skb)从硬件中读取数据位置到申请号的缓冲区里。
接下来填充sk_buff中的一些信息。
中断有可能是收到数据产生也可能是发送完成产生,中断处理程序要对中断类型进行判断,如果是收到数据中断则开始接收数据,如果是发送完成中断,则处理发送完成后的一些操作,比如说重启发送队列。
接收流程:
1、分配skb=dev_alloc_skb(pkt->datalen+2)
2、从硬件中读取数据到skb
3、调用netif_rx将数据交给协议栈。
net_device详解相关推荐
- linux内核中的hook函数详解,linux内核中的hook函数详解
在编写linux内核中的网络模块时,用到了钩子函数也就是hook函数.现在来看看linux是如何实现hook函数的. 先介绍一个结构体: struct nf_hook_ops,这个结构体是实现钩子函数 ...
- linux hook 任意内核函数,linux内核中的hook函数详解
在编写linux内核中的网络模块时,用到了钩子函数也就是hook函数.现在来看看linux是如何实现hook函数的. 先介绍一个结构体: struct nf_hook_ops,这个结构体是实现钩子函数 ...
- 博通wifi驱动详解
1 WLAN技术 WLAN是英文WirelessLAN的缩写,就是无线局域网的意思.无线以太网技术是一种基于无线传输的局域网技术,与有线网络技术相比,具有灵活.建网迅速.个人化等特点.将 ...
- ixgbe网卡驱动 Ⅳ----收发包流程详解
目录 1 网卡队列收包流程概述 2 ixgbe_ring 结构 3 ixgbe 驱动收包流程 3.1 硬件中断入口 ixgbe_msix_clean_rings/ixgbe_intr 3.2 软中断入 ...
- 网络驱动开发样例snull详解(基于3.10.0)
网络驱动开发样例snull详解(基于3.10.0) 本章素材为ldd3书中的网络驱动snull部分.由于现在内核的更新,导致其在最新的内核中无法编译该网络驱动,需要针对修改,顾为此文(内核3.10.0 ...
- ifconfig 与 ip addr 命令详解 - 学习/实践
1.应用场景 主要用于了解学习,掌握使用IP地址相关知识, 如何查看IP信息,以及各个参数代表的含义 2.学习/操作 1.文档阅读 网络协议概论 | Laravel 学院 - 不定期分享之 ifcon ...
- Linux内核中sk_buff结构详解
目录 1.sk_buff结构体 1.1 sk_buff在内核中的结构 1.2 重要的长度len的解析 2. sk_buff数据区 2.1 线性数据区 2.2 非线性数据区 -------------- ...
- linux下iptables和netfilter详解(4):洞悉实现流程及协议栈分析
(一)洞悉linux下的Netfilter&iptables:什么是Netfilter? 很多人在接触iptables之后就会这么一种感觉:我通过iptables命令配下去的每一条规则,到底是 ...
- 从命令行到IDE,版本管理工具Git详解(远程仓库创建+命令行讲解+IDEA集成使用)
首先,Git已经并不只是GitHub,而是所有基于Git的平台,只要在你的电脑上面下载了Git,你就可以通过Git去管理"基于Git的平台"上的代码,常用的平台有GitHub.Gi ...
最新文章
- 量子计算机功率,美国物理学家证明光纤可提升超导量子计算机的功率
- Linux正确的关机方式
- linux运行jar文件
- 【Linux系统编程】进程同步与互斥:System V 信号量
- 七、规则组织的衍生组织——菱形斜纹组织数学模型的建立
- LeetCode 418. 屏幕可显示句子的数量(DP)*
- jvm相关參数,调优
- linux动态ip 搭建什么服务,怎么给Linux系统配置动态IP服务
- Visual Studio 2015 使用ODP.net进行EF开发
- mysql engine 外键_Mysql 外键设置
- 网易新闻 鸿蒙,本报记者体验华为首款鸿蒙产品
- 我与腾讯战斗的那些岁月
- 支持javascript的ppt软件_把PPT放入浏览器中——12款用于演示的JS库
- win10 WIFI连接无选项时的解决方法
- StudentManagerSystem(学生管理系统)(利用Result类,各种工具类)
- 02 Jmonkey3.2.0+Nifty1.4.2实现GUI
- 电脑计算机简单密码设置方法,电脑开机密码怎么设置,开机密码设置很简单!
- 全网最详细IDEA导入eclispe项目
- 标准正态分布正反函数
- Juniper设备标准配置