admin管理员组文章数量:1657738
说明:网卡驱动为网络硬件相关的驱动程序:
一、驱动框架
以drivers/net/ethernet/cirrus/cs89x0.c为例
1、分配一个结构体(内核驱动更多的是类似面向对象):
net_device
2、设置(网卡驱动与上层通信):
发包函数:ndo_start_xmit
收包函数:在中断函数里,用netif_rx
数据包格式:struct sk_buff
3、注册:
register_netdev
4、硬件相关操作:
二、最简单的虚拟网卡实现
新建virt_net/virt_net.c
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/gfp.h>
#include <linux/io.h>
#include <asm/irq.h>
#include <linux/atomic.h>
static struct net_device *vnet_dev;
// 有数据帧要发送时,内核会调用该函数
static int vnet_send_packet(struct sk_buff *skb,struct net_device *dev)
{
// 统计已发送的数据包
dev->stats.tx_packets++;
// 统计已发送的字节
dev->stats.tx_bytes+=skb->len;
// 释放数据帧
dev_kfree_skb(skb);
return 0;
}
// 驱动程序支持的操作
static struct net_device_ops vnet_ops=
{
// 发送数据帧
.ndo_start_xmit=vnet_send_packet,
};
static int __init virt_net_init(void)
{
printk(KERN_ERR "%s,%d\n",__FUNCTION__,__LINE__);
//1、分配一个 net_device 结构体
vnet_dev = alloc_netdev(0, "vnet%d", NET_NAME_UNKNOWN, ether_setup);//生成一个net_device结构体,对其成员赋值并返回该结构体的指针
//2、设置
//网络设备的操作集,这个参数一定要有!否则驱动无法加载
vnet_dev->netdev_ops = &vnet_ops;
//3、注册
register_netdev(vnet_dev);
//4、硬件操作
return 0;
}
static __exit virt_net_exit(void)
{
unregister_netdev(vnet_dev);
free_netdev(vnet_dev);
}
module_init(virt_net_init);
module_exit(virt_net_exit);
MODULE_AUTHOR("zfeng");
MODULE_LICENSE("GPL");
三、测试
insmod virt_net.ko
ifconfig vnet0 1.1.1.1
ifconfig
eth0 Link encap:Ethernet HWaddr 82:48:E9:AB:E7:76
inet addr:10.117.197.11 Bcast:10.117.197.255 Mask:255.255.255.0
inet6 addr: fe80::8048:e9ff:feab:e776/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2509 errors:0 dropped:62 overruns:0 frame:0
TX packets:1160 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2233922 (2.1 MiB) TX bytes:215180 (210.1 KiB)
Interrupt:57
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
vnet0 Link encap:Ethernet HWaddr 01:02:03:04:05:06
inet addr:1.1.1.1 Bcast:1.255.255.255 Mask:255.0.0.0
inet6 addr: fe80::302:3ff:fe04:506/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:578 (578.0 B)
ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1): 56 data bytes
64 bytes from 1.1.1.1: seq=0 ttl=64 time=0.148 ms
64 bytes from 1.1.1.1: seq=1 ttl=64 time=0.088 ms
版权声明:本文标题:Linux内核网卡驱动之(一)——虚拟网卡实现 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1729795183a1212847.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论