網絡卡驅動程式框架
我們這裡說的是網絡卡驅動程式,不是網路驅動程式,網路有七層,我們寫的只是最底層的東西,網路這麼多層,但是最終你還是要操作硬體啊
所以上面肯定有個硬體相關層,我們要寫的就是硬體相關的驅動程式這一小塊。
網絡卡你不需要開啟什麼裝置,你只需要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這個結構體就是統計資訊