一、网络设备驱动

1. 概念

网络设备是Linux的第三类标准设备,没有对应的设备文件,使用内部设备名访问。网络设备及其驱动属于整个TCP/IP协议层的一部分,实现遵循TCP/IP协议栈的要求。
网络设备异步接收外部的数据包,主动请求将硬件收到的数据包交给内核。

2. 网络设备驱动框架

3.套接字缓冲区

sk_buff中重要的字段:

1.各层协议头传输层,网络层,链路层各个协议头
2.数据缓冲区指针head,end,data,tail指向缓冲区的不同位置
3.长度信息有效数据长度

使用sk_buff处理数据包在协议层之间的传递,只需要移动其中的指针,效率比内存拷贝高。

4. sk_buff的操作接口

(1)分配struct sk_buff*dev_alloc_skb(unsigned int len);//分配成功之后,因为还没有存放具体的网络数据包,所以sk_buff的data、tail指针都指向存储空间的起始地址head,而len的大小则为0。(2)释放
void dev_kfree_skb(struct sk_buff *skb);
//用于释放被alloc_skb()函数分配的套接字缓冲区和数据缓冲区(3)指针移动//Linux套接字缓冲区中的数据缓冲区指针移动操作包括put(放置)、push(推)、pull(拉)、reserve(保留)等。//put操作
//将tail指针下移,增加sk_buff的len值,并返回skb->tail原先的值。
unsigned char/skb_put(struct sk_buff *skb, unsigned int len);//push操作
//将data指针上移,因此也要增加sk_buff的len值。
unsigned char*skb_push(struct sk_buff *skb, unsigned int len);//pull操作
//将data指针下移,并减小skb的len值。
unsigned char* skb _pull(struct sk_buff *skb, unsigned int len);//reserve操作
//同时将skb-二data与skb->tail增加len字节数
void skb_reserve(struct sk_buff *skb, unsigned int len);//获取skb->data与skb->head之间空闲空间的大小 static inline unsigned int skb_headroom(const struct sk_buff*skb)//获取skb->tail与skb->end之间空闲空间的大小
⑥static inline int skb_tailroom(const struct sk_buff *skb)

5.net_device结构

net_device在内核中代表一个网络设备,网络设备驱动的实现实际上就是分配填充net device结构并注册到内核的过程,实现上层协议和网络硬件设备之间的数据传递。

net_device是一个巨大的结构体,主要包含网络设备的属性描述和操作接口。实现网络设备驱动只需要了解其中相关的部分即可。

(1)成员组成

 1.全局成员2.硬件相关成员3.接口相关成员4.设备方法成员5.公用成员

1)全局成员

1 char name[ IFNAMSIZ]; //网络设备名
2 int (*init)(struct net_device *dev) ;//net_device初始化函数

2)硬件成员

1 unsigned long mem_end;          /*设备使用共享内存结束地址*/
2 unsigned long mem_start;        /*设备使用共享内存起始地址*/
3 unsigned long base_addr;        /*设备Io基地址*/
4 unsigned int irq;               /*设备使用的中断号*/
5 unsigned char if_port;          /*多端口设备的端口号*/
6 unsigned char dma;              /*DMA通道*/

3)接口相关成员

1 unsigned int mtu;               /*MTU值*/
2 unsigned short type;            /*网络硬件接口类型*/
3 unsigned short hard_header_len; /*网络硬件设备头长度*/
4 unsigned char *dev_addr ;       /*MAc地址*/
5 unsigned int flags;             /*网络接口标志*/

4)设备方法成员

const struct net_device_ops *netdev_ops;//操作函数集合int (*ndo_open)(struct net_device *dev);//打开接口
int (*ndo_stop) ( struct net_device *dev);//停止接口
//初始化数据包的传输,将完整的数据包放入sk_buff中
netdev_tx_t (*ndo_start_xmit) (struct sk_buff *skb, struct net_device *dev)
//数据包发送超时调用的函数,通常是重新发送
void (*ndo_tx_timeout) ( struct net_device *dev);

(2) net_device的注册和注销

int register_netdev(struct net_device *dev);//注册2
void unregister _netdev(struct net_device *dev);//注销

(3)网络设备打开和关闭需要进行的操作

int xxx_open( struct net_device *dev)
{//申请设备资源 ----- IO内存中断DMA.. .//激活设备发送队列void netif_start_queue( struct net_device *dev ) ;
}
int xxx_release( struct net_device *dev)
{//释放设备资源 ----- Io内存中断 DMA. . .//停止设备传输数据包void netif_stop_queue( struct net_device *dev ) ;
}

(4)网络设备发送和超时处理进行的操作

int xxx_tx ( struct sk_buff *skb,struct det_device *dev)
{//从sk_buff中获取有效数据// ...//记录发送时间dev->trans_siart = jiffies;//通过设置网卡硬件的寄存器发送数据包//xxx_hw_tx( data,len, dev);
}
void xxx_tx_timeout( struct det_device *dev)
{// ...//重新发送void netif_wake_queue( struct net_device *dev) ;
}

(5)网络设备数据接收进行的操作

//网卡接收中断函数
void xxx_interrupt(int irq,void *dev_id , struct pt_regs *regs )
{//接收中断//分配sk_buf结构//...//从网卡硬件结束数据// ...//获取上层协议类型skb- >protocol = eth_type_trans(skb, dev);//将数据包交给上层协议层netif_rx( skb);//记录时间戳dev- >last_rx =jiffies;
}

二、编写虚拟网卡驱动

1.先写个模块

#include <linux/init.h>
#include <linux/module.h>static int __init virnet_init(void)
{return 0;
}
static void __exit virnet_exit(void)
{}
module_init(virnet_init);
module_exit(virnet_exit);
MODULE_LICENSE("GPL");

2.写个Makefile编译一下

ifeq ($(arch),arm)
KERNELDIR :=/home/linux/linux-5.10.61
CROSS_COMPILE ?=arm-linux-gnueabihf-
else
KERNELDIR :=/lib/modules/$(shell uname -r)/build
CROSS_COMPILE ?=
endif modname ?=
PWD :=$(shell pwd)CC :=$(CROSS_COMPILE)gccall:make -C $(KERNELDIR) M=$(PWD) modules# $(CC) test.c -o test
clean:make -C $(KERNELDIR) M=$(PWD) clean# rm testinstall:cp *.ko ~/nfs/rootfs/# cp test ~/nfs/rootfs/help:echo "make arch = arm or x86 modname= dirvers file name"obj-m:=$(modname).o

3.再搭个网卡设备驱动框架

#include <linux/init.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>//网络设备结构体指针
struct net_device *virnet_card = NULL;
int virnet_card_init(struct net_device *dev)
{//以太网卡的初始化ether_setup(dev);//设置网卡名strcpy(dev->name,"virnetdevice");printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}
int virnet_card_open(struct net_device *dev)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}netdev_tx_t virnet_card_xmit(struct sk_buff *skb,struct net_device *dev)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}
//操作函数集合
struct net_device_ops vir_netdev_ops = {.ndo_init = virnet_card_init,.ndo_open = virnet_card_open,.ndo_start_xmit = virnet_card_xmit,
};//加载函数
static int __init virnet_init(void)
{//申请net_device空间virnet_card = alloc_etherdev(0);//设置net_devicede 操作函数集合virnet_card->netdev_ops = &vir_netdev_ops;//注册net_deviceregister_netdev(virnet_card);return 0;
}
//卸载函数
static void __exit virnet_exit(void)
{//注销 net_deviecunregister_netdev(virnet_card);//释放net_device空间free_netdev(virnet_card);
}
module_init(virnet_init);
module_exit(virnet_exit);
MODULE_LICENSE("GPL");

3. 编译一下

下载到开发板上

可以看到有新的网卡设备产生

STM32MP157 | 虚拟网卡设备驱动相关推荐

  1. 隐藏在计算机网卡怎样删除,如何卸载电脑中隐藏的虚拟网卡设备

    虚拟网卡主要是建立远程计算机间的局域网,在此虚拟的局域网上能进行所有物理存在的局域网的操作,可以互相访问,可以联网玩游戏.当需要卸载电脑系统中的虚拟网卡时,在设备管理器中无法查看到虚拟网卡设备,那么怎 ...

  2. 张栗炜虚拟键盘设备驱动

    源码:张栗炜虚拟键盘设备驱动 下载地址:http://www.pudn.com/downloads229/sourcecode/windows/vxd/detail1077750.html (yyxh ...

  3. 服务器虚拟网卡卸载不掉,怎么彻底卸载虚拟网卡设备。 彻底卸载虚拟网卡设备的方法。...

    今天给大家带来怎么彻底卸载虚拟网卡设备.,彻底卸载虚拟网卡设备的方法.,让您轻松解决问题.网友求助:求助如何卸载虚拟网卡? 具体方法如下:1 使用Win+R调出运行,在其中输入:devmgmt.msc ...

  4. QEMU虚拟网卡设备的创建流程

    基于qemu-kvm-0.12.1.2-2.160.el6_1.8.src.rpm 虚拟网卡类型为virtio-net-pci virtio网卡设备对应的命令行参数为  -device virtio- ...

  5. [linux-nopage]内存映射虚拟字符设备驱动【P119】

    文章目录 目的:内核空间映射到用户空间 环境:Ubuntu 20.04 linux内核源码5.11.0-37-generic(版本自选) 实验结果 实验知识点 实验难点 实验代码 nopage.c M ...

  6. 虚拟字符设备驱动开发步骤

    目录 前言 字符设备驱动简介 内核驱动操作函数集合(file_operations结构体) 字符设备驱动开发步骤 .ko驱动模块的加载和卸载(module_init驱动入口.insmod驱动加载) 字 ...

  7. Ubuntu查看usb设备驱动/usb以太网卡设备驱动

    step1: lsusb 查看当前有哪些usb设备.注意:插在usb口上的外接设备一定能通过lsusb显示出来,但是不一定能通过lspci显示出来,即使这个设备的驱动已经安装了. 由于我要查看我的有线 ...

  8. Linux 网卡设备驱动

    Linux 网卡驱动 刺猬@http://blog.csdn.net/littlehedgehog 网上一位前辈写的,时至今日,代码很多编译通不过(主要是Linux 内核变化实在太快),我把代码移植到 ...

  9. Wintun:一款惊艳的 WireGuard 虚拟网卡接口驱动

    公众号关注 「奇妙的 Linux 世界」 设为「星标」,每天带你玩转 Linux ! 前一段时间,一直在找寻 Windows 操作系统上的虚拟网卡接口,主要是为了搭建隧道使用.但是 Windows 操 ...

最新文章

  1. 语言趣味编程100例无水印_趣味c语言编程100例(三)
  2. 《因果学习周刊》第7期:因果学习中的离线策略评估
  3. linux下创建mysql用户,并且给增删改查的权限
  4. Web Service学习笔记
  5. HTML --- 盒模型
  6. 【数据挖掘笔记十一】高级聚类分析
  7. 音频开发中常见的四个错误
  8. Mac与centos的ip配置
  9. Tomcat配置可以访问外部资源路径
  10. 小学计算机课评价方案,小学信息技术课堂评价方法的研究
  11. Oracle中集合操作符
  12. 百度云盘群组中资源文件实时同步更新保存到自己群组的方法
  13. 百练4083我爱北大 解析
  14. PS学习笔记------运用脚本及自动化批量处理
  15. IFC学习相关资料加强版 致敬黑夜的骑士
  16. 支付宝推出AR实景红包,开启红包新玩法!
  17. 转:激励,如何做更有效
  18. Word 文件 删除后恢复出现乱码之解决方法
  19. 金融危机,教你从网络上找到一份好兼职
  20. NOIP是什么?全国青少年信息学奥林匹克联赛各区特派员联系名单大全!

热门文章

  1. 支付宝小程序选择手机本地视频
  2. 手机卫士 java_[Java教程]Android 手机卫士2
  3. Openclipart:公共领域图像库
  4. (手机版)生产人员计件扫码系统
  5. 课堂练习 最大联通数组
  6. php随机数各种知识汇集
  7. 用户变量tmp修改了怎么恢复_【热点】安卓手机用户微信可以修改账号啦!如何修改微信号?怎么修改微信号?附图教程...
  8. iOS AVAsset
  9. JavaScript防抖与节流
  10. 计算机可爱的企鹅教案,可爱的企鹅教案