您的位置首页>企业动态>

Linux网络设备驱动程序

导读大家好,我是极客范的本期栏目编辑小友,现在为大家讲解Linux网络设备驱动程序问题。Linux网络设备驱动架构-|数据包发送|数据包接收|-网络

音频解说

大家好,我是极客范的本期栏目编辑小友,现在为大家讲解Linux网络设备驱动程序问题。

Linux网络设备驱动架构

-

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

| dev_queue_xmit() | netif_rx() |

| -

|结构net_device | -网络设备的接口层

-

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

| hard_start_xmit() |数据包接收|

| -

|网络设备媒体(物理层)|-网络设备和媒体层

-

硬件相关驱动程序(提供硬启动xmit,并使用neTIf_rx报告数据)

5.sk_buff socket buffer,用于linux中各层之间的数据传输。当发送数据包时,内核必须创建一个包含传输数据的sk_buff,然后将sk_buff交给下层,每层将它交给sk_buff中的下一层,每层将在sk_buff中添加不同的协议头,直到它被发送到网络设备。接收原理是一样的。

struct sk_buff {

struct sk _ buff * next

struct sk _ buff * prev

struct net _ device * dev

.

char CB[48];

无符号整数,//数据的真实长度

Data_len,//数据长度

mac _ len//链路层帧头的长度

void(*析构函数)(struct sk _ buff * skb);

sk _ buff _ data _ t transport _ header;

sk _ buff _ data _ t network _ header

sk _ buff _ data _ t mac _ header

sk _ buff _ data _ t tail

sk_buff_data_t结束;

无符号字符*head,

*数据;

无符号int truesize

atomic_t用户;

};

5.1.sk_buff结构:

---*头

|头|

|---*数据

|数据|

|缓存|

|---*尾巴

|尾巴|

---*结束

5.2.分布:

分配套接字缓冲区:用GFP_ATOMIC优先级分配skb,因为这个函数经常在设备驱动中调用。

staTIc inline struct sk _ buff * dev _ alloc _ skb(无符号整数长度)

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

staTIc inline struct sk _ buff * alloc _ skb(无符号整数大小,gfp_t优先级)

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; 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;  unsigned short type; unsigned short hard_header_len;

unsigned char dev_addr[MAX_ADDR_LEN];

 void *priv;

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

 unsigned long trans_start;

unsigned long last_rx;

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

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

int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd); int (*set_config)(struct net_device *dev,struct ifmap *map);

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

struct net_device_ops { ..... }; };

 

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。