linux驱动之网卡驱动程序框架
来源:互联网 发布:旭日阳刚成名网络视频 编辑:程序博客网 时间:2024/05/21 05:06
我们这里说的是网卡驱动程序,不是网络驱动程序,网络有七层,我们写的只是最底层的东西,网络这么多层,但是最终你还是要操作硬件啊
所以上面肯定有个硬件相关层,我们要写的就是硬件相关的驱动程序这一小块。
网卡你不需要打开什么设备,你只需要socket编程就行了
怎么写
1、分配某个结构体
2、设置
3、注册
4、硬件相关的操作
然而这个重点在设置这里
首先你得提供发包函数 提供收包的功能
我们随便看一个网卡驱动程序 如cs89x0.c
这是一个真实的网卡驱动程序
分配一个net_device
然后调用了下面这个函数
进去
有个这个
我们看看net_ops
有open和stop函数
还有ndo_start_xmit 硬件启动传输,这个发包函数就在这里
然后注册这个结构体
但是收到数据之后做什么事情,你怎么告诉我收到数据了呢,肯定会有个中断
我们来看看
假设收到数据之后
net_rx 进去看一下
从芯片里面读出来
分配一个skbuf
然后用下面的函数上报
然后我们再看一下发包函数是怎么回事
它发的是什么东西,它的参数是怎样,它的参数是sk_buf
从这里我们可以知道,硬件相关的这层和上层怎么打交道呢?
它们之间就是通过sk_buf,上面这几层构造好包之后,放到sk_buf里面扔给你,调用你的发包函数,你收到数据之后,在你的中断程序收到数据之后,你从芯片里面把数据读出来,构造一个sk_buf,然后用netif_rx来上报这个数据给我
说到这块,写一个网卡驱动很简单,我们先写一个虚拟的网卡
参考/driver/net/cs89x0.c
框架如图
我们来看一下范例里面分配的
但是我们不想用alloc_etherdev这个宏,我们进去看一下这个宏
进入alloc_etherdev_mqs这个函数里面去
这里的名字用的是eth0啊 eth1这种,我不想用这个名字,我想换一个名字,所以我们直接用alloc_netdev_mqs这个函数来做
我们写一个最简单的网络驱动 代码如下
#include <Linux/module.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.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 <asm/system.h>
#include <asm/io.h>a
#include <asm/irq.h>
static struct net_device *vnet_dev;
static int gh_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
static int cnt = 0;
printk("virt_net_send_packet cnt = %d\n", ++cnt);
return 0;
}
static const struct net_device_ops gh_netdev_ops = {
.ndo_start_xmit= gh_start_xmit,
};
static int virtnet_init(void)
{
/*1.分配一个net_device结构体**/
vnet_dev=alloc_netdev(0, "ghnet%d", ether_setup);
/*2.设置*/
vnet_dev->netdev_ops= &gh_netdev_ops;
/*3.注册*/
register_netdev(vnet_dev);
return 0;
}
static void virtnet_exit(void)
{
unregister_netdev(vnet_dev);
free_netdev(vnet_dev);
}
module_init(virtnet_init);
module_exit(virtnet_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("EIGHT");
测试如下
1.insmod virt_net.ko
2.ifconfig ghnet0 3.3.3.3
3.ping 3.3.3.3
效果如图
ping 自己是不会进入那个发包的函数的,我们ping下别人 3.3.3.4
效果如图
这上面说我发了20个包
我们ifconfig来看一下
但是我们这里写的发的包是0,因为我们代码中还没有设置统计信息
在我们net_device结构体中有个net_device_stats这个结构体就是统计信息
- linux驱动之网卡驱动程序框架
- Linux驱动程序之网卡驱动(一)
- Linux设备驱动之USB网卡驱动程序
- linux驱动之USB驱动程序框架
- USB驱动程序之驱动框架
- Linux设备驱动工程师之路——DM9000网卡驱动程序分析
- Linux设备驱动工程师之路——DM9000网卡驱动程序分析
- Linux设备驱动工程师之路——DM9000网卡驱动程序分析(1)
- Linux设备驱动工程师之路——DM9000网卡驱动程序分析(2)
- Linux设备驱动工程师之路——DM9000网卡驱动程序分析(3)
- 网卡驱动程序框架
- linux驱动之网卡驱动-虚拟网卡驱动编写
- Linux驱动之虚拟网卡
- 6410之LCD驱动程序(驱动框架)
- Linux驱动修炼之道-DM9000A网卡驱动框架源码分析
- Linux驱动修炼之道-DM9000A网卡驱动框架源码分析
- linux网卡驱动分析之驱动加载
- linux网卡驱动分析之驱动加载
- Tomcat Can't load AMD 64-bit .dll on a IA 32-bit platform
- iOS学习笔记-079.核心动画05——CAAnimationGroup(动画组)
- 通用的BaseServlet工具类
- oracle 10g安装需注意细节
- 说说你对闭包的理解
- linux驱动之网卡驱动程序框架
- 筛选类and找父级
- char数组转换为LPCTSTR乱码问题 某人的评论里得出的解决方法
- Windows线程同步——临界区对象
- Spring特征
- 请你谈谈Cookie的弊端
- POJ 3104(二分)
- Mysql 密码报错 You must reset your password ... 和 Your password does N
- C语言的strcpy()和strncpy()函数