网卡驱动程序(国嵌笔记)

来源:互联网 发布:软件程序开发 编辑:程序博客网 时间:2024/05/16 13:05
驱动程序的方法:
1.了解在LINUX内核中怎么描述这个设备或者驱动。用什么结构,里面有什么成员、指针(函数,主要是什么功能,什么时间调用)
2.怎么注册驱动程序


网络驱动程序


1.使用struct net_device来描述

使用alloc_netdev或alloc_etherdev来动态分配


关键成员:
char name[IFNAMSIZ] 设备名eth%d  .%d内核来动态分配的,防止驱动冲突
unsigned long state 设备状态
unsigned long base_addr I/O基地址
unsigned int irq 中断号
基本方法
int(*init)(struct net_device *dev) 初始化函数,在register_netdev时被调用来完成对net_device结构的初始化
open 打开接口,ifconfig激活时,接口将被打开
stop 停止接口,
hard_start_xmit 数据发送函数,协议栈通过设备无关接口 ,要求网卡发送数据时调用


可选操作
do_ioctl 处理特定于接口的ioctl命令
set_mac_address改变Mac地址的函数,需要硬件支持该功能,

2.设备注册


他没有主次设备号,使用register_netdev注册


3.sk_buff 

用于在内核中保存一个网络包(地址信息,数据信息等)

指向sk_buff的指针通常被称作skb



主要成员:
struct device *dev;//处理该包的设备
__u32 saddr;//IP源地址
__u32 daddr;//IP目的地址
__u32 raddr;//IP路由地址
unsigned char *head;//分配空间的开始
unsigned char *data;//有效数据的开始
unsigned char *tail;//有效数据的结束
unsigned char *end;//分配空间的结束
unsigned long len;//有效数据长度



操作skb
1.
alloc_skb分配一个sk_buff结构,供协议栈代码使用
dev_alloc_skb分配一个sk_buff结构,供驱动程序使用
2.
skb_push向后移动tail指针,并返回tail移动之前的值,在tail处填充数据,对数据进行扩充
skb_put 向前移动head指针,并返回head移动后的值
3.
kfree_skb释放
dev_kfree_skb释放 


设备打开:(net_device中的open)
open请求任何它需要的系统资源并启动接口:
注册中断、设置寄存器,启动设备、启动发送队列(告诉上层我已准备好了)
在关闭网络的情况下,将中断还给内核。

一般的中断注册放到module_init


int net_open(struct net_device*dev)
{
//申请中断
request_irq(dev->irq,&net_interrupt,SA_SHIRQ,"dm9000",dev);
//设置寄存器,启动设备
············
//启动发送队列
netif_start_queue(dev);
}


数据发送:
当核心需要发送一个数据包时,它调用hard_start_transmit函数,该函数将最终调用到net_device结构中的hard_start_xmit函数指针 (设备无关接口的特性)


数据接受:
网络接口驱动可以实现两种方式的报文接收:中断和查询,linux中多采用中断程序 

(接收发送给自己的、广播包,可配置)会产生接收中断,在此终端中进行接受处理
接受流程
1.分配skb
skb=dev_alloc_skb(pkt->datalen+2)
2.从硬件中读取数据到skb
3.调用netif_rx将数据交给协议栈
netif_rx(skb)


中断处理:
网络接口通常支持3种类型的中断:新报文到达中断、报文发送完成中断和出错中断。
中断处理程序可通过查看网卡中的中断状态寄存器,来分辨出中断类型
0 0
原创粉丝点击