LDD3读书笔记(第13章 网络设备驱动)

来源:互联网 发布:双色球数据库分析 编辑:程序博客网 时间:2024/05/20 16:09

这个小节给出了本章介绍过的概念的快速参考,同时解释了驱动程序应该包含的每个头文件。但是net_device和sk_buff结构的成员不会在这里重复。

#include <linux/netdevice.h>
    这个头文件保存有net_device和net_device_stats结构的定义,并包含了网络驱动程序需要的其他几个头文件。
struct net_device *alloc_netdev(int sizeof_priv,char *name,void (*setup)(struct net_device *));
struct net_device *alloc_etherdev(int sizeof_priv);
void free_netdev(struct net_device *dev);
    分配和释放net_device结构的函数。
int register_netdev(struct net_device *dev);
void unregister_netdev(struct net_device *dev);
    注册和注销一个网络设备。
void *netdev_priv(struct net_device *dev);
    获得指向网络设备结构中驱动程序私有数据区指针的函数。
struct net_device_stats;
    保存设备统计信息的结构。
netif_start_queue(struct net_device *dev);
netif_stop_queue(struct net_device *dev);
netif_wake_queue(struct net_device *dev);
    上述函数控制外发数据包向驱动程序的传递。在调用netif_start_queue之前,不会传输任何数据包。netif_stop_queue暂停传输,而netif_wake_queue重新启动队列并通知网络层重新启动数据包的传输。
skb_shinfo(struct sk_buff *skb);
    提供对数据包缓冲区中“共享信息”访问的宏。
void netif_rx(struct sk_buff *skb);
    调用(包括中断期间)这个函数可通知内核已经接收到一个数据包,冰封装入一个套接字缓冲区。
void netif_rx_schedule(dev);
    调用该函数通知内核数据包已经存在,并且在接口上启动轮询机制;它只在NAPI驱动程序中使用。
int netif_receive_skb(struct sk_buff *skb);
void netif_rx_complete(struct net_device *dev);
    这两个函数只在NAPI驱动程序中使用。NAPI中的netif_receive_skb函数与netif_rx等价;它将数据包发送给内核。当NAPI驱动程序耗尽了为接收数据包准备的内存,则它将重新启动中断,然后调用netif_rx_complete终止轮询函数。
#include <linux/if.h>
    netdevice.h中包含该头文件。在该文件中声明了接口标志(IFF_macros)和ifmap结构,在网络驱动程序的ioctl实现中,其扮演了重要角色。
void netif_carrier_off(struct net_device *dev);
void netif_carrier_on(struct net_device *dev);
int netif_carrier_ok(struct net_device *dev);
    前两个函数告诉内核在指定接口上是否存在载波信号。netif_carrier_ok检查载波状态作为在device结构中的应答。
#include <linux/if_ether.h>
ETH_ALEN
ETH_P_IP
struct ethhdr;
    netdevice.h中包含该头文件。if_ether.h中定义了所有的ETH_宏、用来表示octet的长度(比如地址长度)和网络协议(比如IP)。它还定义了ethhdr结构。
#include <linux/skbuff.h>
    定义了sk_buff及其相关的结构,同时定义了许多作用于缓冲区的内联函数。该头文件包含在netdevice.h中。
struct sk_buff *alloc_skb(unsigned int len,int priority);
struct sk_buff *dev_alloc_skb(unsigned int len);
void kfree_skb(struct sk_buff *skb);
void dev_kfree_skb(struct sk_buff *skb);
void dev_kfree_skb_irq(struct sk_buff *skb);
void dev_kfree_skb_any(struct sk_buff *skb);
    分配和释放套接字缓冲区的函数。因此驱动程序通常使用有dev_前缀的变种。
unsigned char *skb_put(struct sk_buff *skb,int len);
unsigned char *__skb_put(struct sk_buff *skb,int len);
unsigned char *skb_push(struct sk_buff *skb,int len);
unsigned char *__skb_push(struct sk_buff *skb,int len);
    将数据添加到skb的函数;skb_put将数据放在skb的末尾,而skb_push将数据放在开头,常用的版本还负责检查是否有足够的空间存放数据;而有双下划线前缀的版本不进行该项检查。
int skb_headroom(stryct sk_buff *skb);
int skb_tailroom(struct sk_buff *skb);
void skb_reserve(struct sk_buff *skb,int len);
在skb中实现空间管理的函数。skb_headroom和skb_tailroom分别返回在skb的开头和结尾,还有多少空间可用。skb_reserve用于在skb开头部分保留空间,保留的空间必须唯恐。
unsigned char *skb_pull(struct sk_buff *skb,int len);
    skb_pull通过调整内部指针而“删除”skb内的数据。
int skb_is_nonlinear(struct sk_buff *skb);
    如果使用分散/聚集I/O,并且skb分离成多个数据片段,则该函数返回真实值。
int skb_headlen(struct sk_buff *skb);
    返回skb中skb->data 的第一个段的长度。
void *kmap_skb_frag(skb_frag_t *frag);
void kunmap_skb_frag(void *vaddr);
    提供对非线性skb中的数据片段的直接访问。
#include <linux/etherdevice.h>
void ether_setup(struct net_device *dev);
    为以太网驱动程序设置大部分通用设备方法的函数。它还设置了dev->flags。如果设备名称的第一个字符为空,或者是空格的话,这个函数将把下一个可用 的ethx名称赋给dev->name。
unsigned short eth_type_trans(struct sk_buff *skb,struct net_device *dev);
    当以太网接口接收到一个数据包时,调用该函数设置skb->pkt_type。返回值是保存早skb->protocol中的协议号。
#include <linux/sockios.h>
SIOCDEVPRIVATE
    16个ioctl命令中的第一个,每个驱动程序都能够出于自身的考虑实现它。在sockios.h中定义了所有的网络ioctl命令。
#include <linux/mii.h>
struct mii_if_info;
    支持实现MII标准的设备驱动程序的声明和结构。
#include <linux/ethtool.h>
struct ethtool_ops;
    让设备可使用ethtool工具的声明和结构。

原创粉丝点击