网卡驱动程序

1、网络子系统(如下的内核空间的几层)

用户空间     应用层

内核空间     系统调用   通过socket访问网络子系统

内核空间     协议无关接口    一组通用函数通过socket访问不同协议

内核空间     网络协议层 各种传输层网络层协议tcp udp ip

内核空间     设备无关接口

内核空间     设备驱动

                 硬件设备

2、网卡驱动

设备描述:

每个网络接口都由一个net_device结构来描述,可使用如下内核函数动态分配

struct net_device *alloc_netdev(int sizeof_priv, constr char *mast设备名, void (*setup)(struct net_device *))

struct net_device *alloc_etherdev(int sizeof_priv)

这两个函数有什么关系呢?

struct net_device

          {char name[IFNAMESIZ]    设备名,如eth%d   "%"表示这个数字由动态的分配编号,以防号冲突

             unsigned long state        设备状态

             unsigned long base_addr i/o基地址

             unsigned int irq                 中断号

             int (*init)(struct net_device *dev)   在register_netdev时被调用来完成对net_device结构的初始化

             int (*open)(struct net_device *dev) 打开接口,ifconfig激活时,接口将被打开

             int (*stop)(sturct net_device *dev)

             int (*hard_start_xmit)(struct sk_buff *skb, struct net_device *dev)   数据发送函数

             int (*do_ioctl)...

             int (*set_mac_address)...  改变硬件地址 需要硬件支持该功能

             }

设备描述:

int register_netdev(struct net_device *dev)

注册方式与字符驱动不同之处在于它没有主次设备号,它不是通过设备文件方问,能过socket来问问;

struct sk_buffer{

             struct device *dev;   处理该包的设备

             __u32 saddr;        ip源地址

             __u32 saddr;        ip上的地址

             __u32 raddr;        ip路由器地址

             __unsigned char *head   分配空间的开始

             __unsigned char *data    有效数据的开始

             __unsigned char *tail      有效数据的结束

             __unsigned char *end     分配空间的结束

             unsigned long  len;          有效数据的长度

            }

它描述一个网络数据包。

skb操作函数

struct sk_buff *alloc_skb(unsigned int len , int priority)

分配一个sk_buff结构,供协议栈代码使用

struct sk_buff *dev_alloc_skb(unsigned int len)

分配一个sk_buff结构,供驱动代码使用,形成一个skb结构,交给上层协议去处理

unsigned char *skb_push(struct sk_buff *skb, int len)

向后移动skb的tail指针,并返回tail移动之前的值;用于先有协议头的情况下向后填充数据;返回移动之前的地址是用于从那里开始填数据;

unsigned char *skb_put(struct sk_buff *skb, int len)

向前移动skb的head指针,并返回head移动之后的值;用于先有数据的情况下在前边加协议头;

kfree_skb(struct sk_buff *skb)

释放一个sk_buff结构,供协议栈代码使用

dev_dfree_skb(struct sk_buff *skb)

释放一个sk_buff结构,供驱动代码使用

 

网卡驱动

设备打开

open请求任何它需要的系统资源并且启动接口:

1、注册中断,DMA等(一般的字符驱动模块加载的时候就注册中断,因为它们会一直使用)

2、设置寄存器,启动设备

3、启动发送队列,

 

数据发送

当核心需发送一个数据包时,它调用hard_start_transmit函数,该函数根据io,路由等规则找到处理该包的网卡,将最终调用到该网卡的net_device结构中的hard_start_xmint函数

 

数据接收

中断方式,当包到达网卡后,它会产生一个接收中断,接着在包的处理程序中进行包的接收工作,如下三步:

1、分配skb  skb=dev_alloc_skb(pkt-datalen+2)

2、从硬件中读取数据到skb

3、调用netif_rx(skb)将数据交给协议栈

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值