linux网络设备驱动
Linux网络设备驱动
Linux网络驱动程序的体系结构可划分为4个层次。Linux内核源代码中提供了网络设备接口及以网络子系统的上层的代码,移植特定网络硬件的驱动程序的主要工作就是完成设备驱动功能层的相应代码,根据底层具体的硬件特性,定义网络设备接口struct net_device类型的结构体变量,并实现其中相应的操作函数及中断处理程序。
Linux中所有的网络设备都抽象为一个统一的接口,即网络设备接口,通过struct net_device类型的结构体变量表示网络设备在内核中的运行情况,这里既包括回环(loopback)设备,也包括硬件网络设备接口。内核通过以dev_base为头指针的设备链表来管理所有的网络设备。
设备操作函数
打开:int (*open)(struct net_device *dev); //获得设备需要的IO地址,IRQ及DMA通道
关闭:int (*stop)(struct net_device *dev);
启动数据包发送:int (*hard_start_xmit)(struct sk_buff *skb, struct net_device *dev);
获得网络设备状态:struct net_device_status * (*get_status)(struct net_device *dev);
设备I/O控制:int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);
配置接口、I/O地址:int (*set_config)(struct net_device *dev, struct ifmap *map);
设置MAC地址:int (*set_mac_address)(struct net_device *dev, void *addr);
套接字缓冲区sk_buff相关操作:
分配空间:struct sk_buff *dev_alloc_skb(unsigned len)
释放空间:
dev_kfree_skb(struct sk_buff *skb); //用于非中断上下文
dev_kfree_skb_irq(struct sk_buff *skb); //用于中断上下文
dev_kfree_skb_any(struct sk_buff *skb); //上述两种情况均可
put操作:
unsigned char *skb_put(struct sk_buff *skb, unsigned int len);
unsigned char *__skb_put(struct sk_buff *skb, unsigned int len);
作用:在缓冲区尾部添加数据,tail指针下移len长度,并增加sk_buff中len的值,返回改变后的tail值。
push操作:
unsigned char *skb_push(struct sk_buff *skb, unsigned int len);
unsigned char *__skb_push(struct sk_buff *skb, unsigned int len);
作用:将data指针上移,同时增加sk_buff中的len。主要用于在数据包发送时添加头部。函数带__和不带__的区别在于:带__的会检测放入缓冲区的数据,后则不会。
pull操作:
unsigned char *skb_pull(struct sk_buff *skb, unsigned int len);
作用:将data指针下移,并减少sk_buff中的len值。这个操作一般用于下层协议向上层协议移交数据包,使data指针指向上一层协议的协议头。
reserve操作:
void skb_reserve(struct sk_buff *skb, unsigned int len);
作用:将data和tail指针同时下移,这个操作主要用于在存储空间的头部预留len长度的空隙。
网络设备接口层:
struct net_device_ops {
int (*ndo_init)(struct net_device *dev);
void (*ndo_uninit)(struct net_device *dev);
int (*ndo_open)(struct net_device *dev);
int (*ndo_stop)(struct net_device *dev);
int (*ndo_start_xmit) (struct sk_buff *skb,struct net_device *dev);
u16 (*ndo_select_queue)(struct net_device *dev,struct sk_buff *skb);
......
}
实现这些函数中的一部分后,就实现了驱动的功能了,为千变万化的网络设备定义统一的、抽象的数据结构net_device结构体,以不变应万变,实现多种硬件在软件层次上的统一。net_device结构体在内核中指代一个网络设备,网络设备驱动只需填充其结构体就可以实现内核与具体硬件操作函数的挂接。实际驱动的编写过程中,我们并不需要实现全部的函数,实际上,我们只要根据具体的需要实现上边的部分就可以了。
Linux网络设备驱动程序实现:

代码编写步骤:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
static int gecnet_init(struct net_device *dev)
static void gecnet_uninit(struct net_device *dev)
static int gecnet_open(struct net_device *dev){
netif_start_queue(dev);
}
static int gecnet_stop(struct net_device *dev){
netif_stop_queue(dev);
}
static netdev_tx_t gecnet_start_xmit(struct sk_buff *skb,struct net_device *dev){ //发包
//hw_net_write(skb->data,skb->len,offset);//将数据写入硬件寄存器
dev->stats.tx_bytes += skb->len;//更新状态数据
dev_kfree_skb(skb); //释放sk_buff空间
return NETDEV_TX_OK;
}
static int gec_net_rx(struct net_device *dev){ //收包
skb = dev_alloc_skb(RxLen + 4); //data_len 由网卡芯片获取
skb_reserve(skb, 2);
memcpy(skb_put(skb, RxLen - 4),data,RxLen);//data 为硬件接受到的数据地址
dev->stats.rx_bytes += RxLen;
dev->stats.rx_packets++;
skb->protocol = eth_type_trans(skb, dev);
skb->ip_summed = CHECKSUM_UNNECESSARY; //测试使用
netif_rx(skb); //往内核协议层提交数据包
}
struct net_device_ops gec_netops ={
.ndo_init = gecnet_init,
.ndo_uninit = gecnet_uninit,
.ndo_open = gecnet_open,
.ndo_stop = gecnet_stop,
.ndo_start_xmit = gecnet_start_xmit,
};
static int __init gec_net_init(void){
gec_dev = alloc_etherdev(sizeof(struct net_device));
ether_setup(gec_dev);
gec_dev->stats.rx_packets = 0;
gec_dev->stats.tx_packets = 0;
gec_dev->stats.rx_bytes = 10;
gec_dev->stats.tx_bytes = 10;
gec_dev->netdev_ops = &gec_netops;
gec_dev->ml_priv = &gec_netops;
for(i=0;i<6;i++)
dev_addr[i] = 0x33;
gec_dev->dev_addr = dev_addr;
sprintf(gec_dev->name,"gec_net%d",0);
ret = register_netdev(gec_dev);
}
static void __exit gec_net_exit(void)
{
unregister_netdev(gec_dev);
free_netdev(gec_dev);
}
module_init(gec_net_init);
module_exit(gec_net_exit);
MODULE_LICENSE("GPL");
相关资料下载链接:http://download.csdn.net/detail/klcf0220/5905511
示例代码下载链接:http://download.csdn.net/detail/klcf0220/5905519
linux网络设备驱动的更多相关文章
- Linux网络设备驱动架構學習(三)
Linux网络设备驱动架構學習(三) 接下來會從以下幾個方面介紹網絡設備驅動的編寫流程: 1.網絡設備的註冊與註銷 2.網絡設備的初始化 3.網絡設備的打開與釋放 4.網絡數據發送流程 5.網絡數據接 ...
- Linux网络设备驱动架構學習(二)
Linux网络设备驱动架構學習(二) 接下來會從以下幾個方面介紹網絡設備驅動的編寫流程: 1.網絡設備的註冊與註銷 2.網絡設備的初始化 3.網絡設備的打開與釋放 4.網絡數據發送流程 5.網絡數據接 ...
- Linux网络设备驱动(一) _驱动模型
Linux素来以其强大的网络功能著名,同时, 网络设备也作为三大设备之一, 成为Linux驱动学习中必不可少的设备类型, 此外, 由于历史原因, Linux并没有强制对网络设备贯彻其"一切皆 ...
- Linux网络设备驱动架构
Linux网络设备驱动程序体系结构分为四层:网络协议接口层.网络设备接口层.提供实际功能的设备驱动层以及网络设备与媒介层. (1)网络协议接口层向网络层协议提供统一的数据包收发接口,不论上层协议是AR ...
- Linux网络设备驱动 _驱动模型
Linux素来以其强大的网络功能著名,同时, 网络设备也作为三大设备之一, 成为Linux驱动学习中必不可少的设备类型, 此外, 由于历史原因, Linux并没有强制对网络设备贯彻其"一切皆 ...
- Linux 网络设备驱动开发(一) —— linux内核网络分层结构
Preface Linux内核对网络驱动程序使用统一的接口,并且对于网络设备采用面向对象的思想设计. Linux内核采用分层结构处理网络数据包.分层结构与网络协议的结构匹配,既能简化数据包处理流程,又 ...
- linux 网络设备驱动
linux 网络驱动 谨以此文纪念过往的岁月 一.前言在linux中网络驱动也是一个大头,如何去理解网络驱动是作为一个linux驱动工程师必备的技能.不过同样的设备,在不同人的手中会有不同的效果,其原 ...
- 《linux设备驱动开发详解》笔记——14 linux网络设备驱动
14.1 网络设备驱动结构 网络协议接口层:硬件无关,标准收发函数dev_queue_xmit()和netif_rx(); 注意,netif_rx是将接收到的数据给上层,有时也在驱动收到数据以后调用 ...
- Linux网络设备驱动的实现
结论: 1.对一个设备驱动而言,主要从两个方面进行着手,一个是控制流,一个是数据流. 控制流就是如何控制网络设备,数据流则说的是报文的收发流程. 2.网络设备可以是Linux服务器的网卡,也可以是嵌入 ...
随机推荐
- Luogu 2668 NOIP 2015 斗地主(搜索,动态规划)
Luogu 2668 NOIP 2015 斗地主(搜索,动态规划) Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来 ...
- 斯坦福大学公开课机器学习:梯度下降运算的特征缩放(gradient descent in practice 1:feature scaling)
以房屋价格为例,假设有两个特征向量:X1:房子大小(1-2000 feets), X2:卧室数量(1-5) 关于这两个特征向量的代价函数如下图所示: 从上图可以看出,代价函数是一个又瘦又高的椭圆形轮廓 ...
- echarts3地图如何添加点击事件? 点击地图相应的区域ajax获取并展示本区域省下面所有市的信息
myChart.on('click', function (params) { var city = params.name; loadChart(city); });
- centos中文字符集,中文日志
# CentOS 7 $ firewall-cmd --zone=public --add-port=80/tcp --permanent # nginx 端口 $ firewall-cmd --zo ...
- 音乐播放和视频播放--pyglet(一)
最近,开始学习pyglet库.通过几天的学习,深刻的体会了python第三方模块的强大.我一直想做多媒体开发,曾经尝试用C语言进行编写,但是C语言在GUI开发上难度较大,要写一个界面出来得码很多冗余的 ...
- 【已解决】Microsoft visual c++ 14.0 is required问题解决办法
装 识别图形验证码库tesserocr的时候,出现了Microsoft visual c++ 14.0 is required的问题,用离线安装还是没有用. 就只能乖乖装Microsoft visua ...
- ping的作用
Ping是潜水艇人员的专用术语,表示回应的声纳脉冲,在网络中Ping 是一个十分好用的TCP/IP工具.它主要的功能是用来检测网络的连通情况和分析网络速度. Ping有好的善的一面也有恶的一面.先说一 ...
- my live bigdata
s 上海移动 13585845289 张xx,安徽六安,下沙镇,沪南公路,X菇种植. 自然人严重失信黑名单查询 http://www.jscredit.gov.cn/credit/p/rb_list/ ...
- 设计模式---对象创建模式之构建器模式(Builder)
一:概念 Builder模式也叫建造者模式或者生成器模式,是由GoF提出的23种设计模式中的一种.Builder模式是一种对象创建型模式之一,用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象 ...
- 如何下载网易云音乐APP里的MV和短视频?
本人:网易云音乐死粉,朋友圈大多都用的是云音乐,因为推荐功能牛逼 然后:发现云音乐APP里越来越多吸引我的短视频,经常看到好的就想保存到相册,然后微信发给朋友 但是:不知道怎么下载网易云音乐的短视频, ...