STM32MP157 | 虚拟网卡设备驱动
一、网络设备驱动
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 | 虚拟网卡设备驱动相关推荐
- 隐藏在计算机网卡怎样删除,如何卸载电脑中隐藏的虚拟网卡设备
虚拟网卡主要是建立远程计算机间的局域网,在此虚拟的局域网上能进行所有物理存在的局域网的操作,可以互相访问,可以联网玩游戏.当需要卸载电脑系统中的虚拟网卡时,在设备管理器中无法查看到虚拟网卡设备,那么怎 ...
- 张栗炜虚拟键盘设备驱动
源码:张栗炜虚拟键盘设备驱动 下载地址:http://www.pudn.com/downloads229/sourcecode/windows/vxd/detail1077750.html (yyxh ...
- 服务器虚拟网卡卸载不掉,怎么彻底卸载虚拟网卡设备。 彻底卸载虚拟网卡设备的方法。...
今天给大家带来怎么彻底卸载虚拟网卡设备.,彻底卸载虚拟网卡设备的方法.,让您轻松解决问题.网友求助:求助如何卸载虚拟网卡? 具体方法如下:1 使用Win+R调出运行,在其中输入:devmgmt.msc ...
- QEMU虚拟网卡设备的创建流程
基于qemu-kvm-0.12.1.2-2.160.el6_1.8.src.rpm 虚拟网卡类型为virtio-net-pci virtio网卡设备对应的命令行参数为 -device virtio- ...
- [linux-nopage]内存映射虚拟字符设备驱动【P119】
文章目录 目的:内核空间映射到用户空间 环境:Ubuntu 20.04 linux内核源码5.11.0-37-generic(版本自选) 实验结果 实验知识点 实验难点 实验代码 nopage.c M ...
- 虚拟字符设备驱动开发步骤
目录 前言 字符设备驱动简介 内核驱动操作函数集合(file_operations结构体) 字符设备驱动开发步骤 .ko驱动模块的加载和卸载(module_init驱动入口.insmod驱动加载) 字 ...
- Ubuntu查看usb设备驱动/usb以太网卡设备驱动
step1: lsusb 查看当前有哪些usb设备.注意:插在usb口上的外接设备一定能通过lsusb显示出来,但是不一定能通过lspci显示出来,即使这个设备的驱动已经安装了. 由于我要查看我的有线 ...
- Linux 网卡设备驱动
Linux 网卡驱动 刺猬@http://blog.csdn.net/littlehedgehog 网上一位前辈写的,时至今日,代码很多编译通不过(主要是Linux 内核变化实在太快),我把代码移植到 ...
- Wintun:一款惊艳的 WireGuard 虚拟网卡接口驱动
公众号关注 「奇妙的 Linux 世界」 设为「星标」,每天带你玩转 Linux ! 前一段时间,一直在找寻 Windows 操作系统上的虚拟网卡接口,主要是为了搭建隧道使用.但是 Windows 操 ...
最新文章
- 语言趣味编程100例无水印_趣味c语言编程100例(三)
- 《因果学习周刊》第7期:因果学习中的离线策略评估
- linux下创建mysql用户,并且给增删改查的权限
- Web Service学习笔记
- HTML --- 盒模型
- 【数据挖掘笔记十一】高级聚类分析
- 音频开发中常见的四个错误
- Mac与centos的ip配置
- Tomcat配置可以访问外部资源路径
- 小学计算机课评价方案,小学信息技术课堂评价方法的研究
- Oracle中集合操作符
- 百度云盘群组中资源文件实时同步更新保存到自己群组的方法
- 百练4083我爱北大 解析
- PS学习笔记------运用脚本及自动化批量处理
- IFC学习相关资料加强版 致敬黑夜的骑士
- 支付宝推出AR实景红包,开启红包新玩法!
- 转:激励,如何做更有效
- Word 文件 删除后恢复出现乱码之解决方法
- 金融危机,教你从网络上找到一份好兼职
- NOIP是什么?全国青少年信息学奥林匹克联赛各区特派员联系名单大全!