linux网络设备驱动视频,Linux网络设备驱动程序

Linux网络设备驱动程序体系结构

--------------------------------------

? ? |? ? ? ? 数据包发送? ? |? ? 数据包接收? ? ? |? ? ----->网络协议接口层

? ? |? dev_queue_xmit() |? ? netif_rx()? ? ? |

? ? |--------------------------------------

? ? |? ? ? ? ? ? 结构体 net_device? ? ? ? ? |? ? ----->网络设备接 口层

? ? --------------------------------------

? ? |? ? ? ? 数据包发送? ? ? |? ? ? 中断处理? ? ? |? ? ----->网络驱动功能层

? ? |? hard_start_xmit() |? ? 数据包接收? ? ? |

? ? |--------------------------------------

? ? |? ? ? ? 网络设备媒介(物理层)? ? ? ? ? |? ? ----->网络设备与媒介层

? ? --------------------------------------

硬件相关的驱动程序(要提供hard_start_xmit, 有数据时要用neTIf_rx上报)

5.sk_buff套接字缓冲区,用于linux中各层之间传输数据。当要发送数据包的时候,内核必须建立一个包含传输数据的sk_buff,然后将sk_buff交给下层,各层在sk_buff递交给下一层,各层在sk_buff中添加不同的协议贞头,直到交给网络设备发送。接收原理相同。

struct sk_buff {

?/* These two members must be first. */

?struct sk_buff *next;

?struct sk_buff *prev;

?/*网络设备接口层中的net_devive结构体*/

struct net_device *dev;

?....

/*控制缓冲区 ,每个层都可以使用它,用于存放私有数据*/

char cb[48];

unsigned int len, //数据真实长度

data_len,//数据长度

mac_len; //链接层帧头的长度

/*钩子函数 垃圾回收*/

void (*destructor)(struct sk_buff *skb);

sk_buff_data_t transport_header;?

?sk_buff_data_t network_header;

?sk_buff_data_t mac_header;

?/* These elements must be at the end, see alloc_skb() for details. */

?sk_buff_data_t tail;

?sk_buff_data_t end;

?unsigned char *head,

?*data;

?unsigned int truesize;

?atomic_t users;

?};

5.1、sk_buff结构:

----------- ---->*head

?| 头部 |

?|------------ ---->*data

?| 数据 |

?| 缓存 |

?|----------- ---->*tail

?| 尾部 |

----------- ---->*end

5.2、分配:

?分配套接字缓冲区:以GFP_ATOMIC优先级进行skb的分配,因为该函数经常在设备驱动中被调用

staTIc inline struct sk_buff *dev_alloc_skb(unsigned int length)

分配一个套接字缓冲区和一个数据缓冲区,参数len为数据缓冲区的大小,ARM通常32位对齐,参数priority为内存分配的优先级。

staTIc inline struct sk_buff *alloc_skb(unsigned int size,gfp_t priority)

5.3、释放:

//用于释放dev_alloc_skb的内存,用于非中断上下文中

void dev_kfree_skb(struct sk_buff *skb)

?//用于中断上下文中

staTIc inline void dev_kfree_skb_irq(struct sk_buff *skb)

?//中断和非中断都可以用 any,其实就是做了一个判断

void dev_kfree_skb_any(struct sk_buff *skb)

?{

?if (in_irq() || irqs_disabled())

?dev_kfree_skb_irq(skb);

?else

?dev_kfree_skb(skb);

?}

5.4、变更:

?缓冲区尾部增加数据 skb

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

?skb->tail += len;

?skb->len += len;

缓冲区开头增加数据

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

?skb->data -= len;

?skb->len += len;

缓冲区开头移除数据

static inline unsigned char *skb_pull(struct sk_buff *skb, unsigned int len)

?skb->len -= len;

?return skb->data += len;

调节缓冲区头部

static inline void skb_reserve(struct sk_buff *skb, int len)

?skb->data += len;

?skb->tail += len;

6.net_device结构体

struct net_device

?{

?/*网络设备名称*/

char name[IFNAMSIZ];

unsigned long mem_end; /* 共享内存结束地址 */

unsigned long mem_start; /* 共享内存开始地址 */

unsigned long base_addr; /* I/O设备的基地址 */

unsigned int irq; /* 设备中断号 */

unsigned char if_port; /* 多端口设备使用哪一个端口*/

unsigned char dma; /* DMA channel

/*设备初始化函数,只被调用一次 */

int (*init)(struct net_device *dev);

/*用于获取网络设备的状态信息*/

struct net_device_stats* (*get_stats)(struct net_device *dev);

?/*存放详细的网络设备流量统计信息*/

struct net_device_stats stats;

.......................

?unsigned mtu; /* interface MTU(最大传输单元) value*/

?unsigned short type; /* 硬件接口类型 */

unsigned short hard_header_len; /* 硬件头的长度 */

/*MAC地址*/

unsigned char dev_addr[MAX_ADDR_LEN];

/*私有数据,用于存放私有的数据,netdev_priv()*/

?void *priv;

/*启动数据包的发送*/

int (*hard_start_xmit) (struct sk_buff *skb,struct net_device *dev);

/*开始发送数据时候的时间戳 格式为:jiffies */

?unsigned long trans_start;

/* 最后一次接受数据包的长度 */

unsigned long last_rx;

/* open用于打开网络设备,获取所需的IO地址和中断号.stop()用于停止网络设备 */

int (*open)(struct net_device *dev);

?int (*stop)(struct net_device *dev);

?/*用于设置设备的MAC地址*/

int (*set_mac_address)(struct net_device *dev,void *addr);

/*进行特定的IO控制*/

int (*do_ioctl)(struct net_device *dev,

?struct ifreq *ifr, int cmd);

?/*用于配置接口,可以用来改变设备的IO地址和中断号*/

int (*set_config)(struct net_device *dev,struct ifmap *map);

/*数据包发送超时时候会被调用,可以用来重启网卡*/

void (*tx_timeout) (struct net_device *dev);

/*linux4.0才有的一个结构体,linux2.6没有,操作硬件的集合*/

struct net_device_ops {

?.....

?};

?};

?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值