Linux驱动_网络驱动简介

参考:Linux设备驱动开发详解(宋宝华)

        网络设备完成用户数据包在网络媒介上的发送和接收的设备,它讲上层协议的传递的数据包以媒介访问的方式进行发送,并将接收到的数据传递给上层协议。     

一、Linux网络设备结构图

        ① 网络协议接口层:该层的存在使设备独立于上层协议,即不管上层网络采用什么协议都通过dev_queue_xmit()发送数据,netif_rx()接收数据。
        ② 网络设备接口层:net_device是描述具体的网络属性和操作的结构体,并且是设备驱动功能层中各函数的容器。
        ③ 设备驱动功能层:net_device结构体中各函数的具体实现,驱使网络设备硬件完成相应的功能。
        ④ 网络设备与媒介层:完成数据发送和接收的物理实体,对于Linux来说可以是虚拟的。

二、网络协议接口层

该层的功能是给上层网络协议提供透明的传输。

① 当上层需要发送数据的时候调用dev_queue_xmit()函数

int dev_queue_xmit(struct sk_buff *skb)

② 当上层需要接收数据的时候调用netif_rx()函数

int netif_rx(struct sk_buff *skb)

        两个函数的参数都是sk_buff结构体,定义域include/linux/skbuff.h中,该结构体相当于数据传递的中枢。
        发送数据的时候,Linux内核的网络处理模块会建立一个sk_buff,然后传递给下层,每层添加不同的协议头文件,最后进行发送。
        接收数据的时候,网络设备将数据包向上传递,各层剥去对应的协议头文件,最后交给上层用户。

三、网络设备接口层

        该层的主要功能是提供net_device结构体,多种硬件在软件层次上的统一。
        net_device在内核中指代一个具体的网络设备,定义于include/linux/netdevice.h中,具体的定义内容如下:

1 struct net_device {
2 char name[IFNAMSIZ];
3 struct hlist_node name_hlist;
4 char *ifalias;
5 /*
6 * I/O specific fields
7 * FIXME: Merge these and struct ifmap into one
8 */
9 unsigned long mem_end;
10 unsigned long mem_start;
11 unsigned long base_addr;
12 int irq;
13
14 atomic_t carrier_changes;
15
16 /*
17 * Some hardware also needs these fields (state,dev_list,
18 * napi_list,unreg_list,close_list) but they are not
19 * part of the usual set specified in Space.c.
20 */
2122 unsigned long state;
23
24 struct list_head dev_list;
25 struct list_head napi_list;
26 struct list_head unreg_list;
27 struct list_head close_list;
......
60 const struct net_device_ops *netdev_ops;
61 const struct ethtool_ops *ethtool_ops;
62 #ifdef CONFIG_NET_SWITCHDEV
63 const struct swdev_ops *swdev_ops;
64 #endif
65
66 const struct header_ops *header_ops;
67
68 unsigned int flags;
......
77 unsigned char if_port;
78 unsigned char dma;
79
80 unsigned int mtu;
81 unsigned short type;
82 unsigned short hard_header_len;
83
84 unsigned short needed_headroom;
85 unsigned short needed_tailroom;
86
87 /* Interface address info. */
88 unsigned char perm_addr[MAX_ADDR_LEN];
89 unsigned char addr_assign_type;
90 unsigned char addr_len;
......
130 /*
131 * Cache lines mostly used on receive path (including
eth_type_trans())
132 */
133 unsigned long last_rx;
134
135 /* Interface address info used in eth_type_trans() */
136 unsigned char *dev_addr;
137
138
139 #ifdef CONFIG_SYSFS140 struct netdev_rx_queue *_rx;
141
142 unsigned int num_rx_queues;
143 unsigned int real_num_rx_queues;
144
145 #endif
......
158 /*
159 * Cache lines mostly used on transmit path
160 */
161 struct netdev_queue *_tx ____cacheline_aligned_in_smp;
162 unsigned int num_tx_queues;
163 unsigned int real_num_tx_queues;
164 struct Qdisc *qdisc;
165 unsigned long tx_queue_len;
166 spinlock_t tx_global_lock;
167 int watchdog_timeo;
......
173 /* These may be needed for future network-power-down code. */
174
175 /*
176 * trans_start here is expensive for high speed devices on SMP,
177 * please use netdev_queue->trans_start instead.
178 */
179 unsigned long trans_start;
......
248 struct phy_device *phydev;
249 struct lock_class_key *qdisc_tx_busylock;
250 };

四、设备驱动功能层

         net_device结构体的成员(属性和net_device_ops结构体中的函数指针)需要被设备驱动功能层赋予具体的数值和函数。对于具体的设备xxx,工程师应该编写相应的设备驱动功能层的函数,这些函数形如xxx_open().xxx_stop()、xxx_tx()、xxx_hard_header()、xxx_get_stats(和 xxx_tx_timcout()等。

        由于网络数据包的接收可由中断引发,设备驱动功能层中的另一个主体部分将是中断处理函数,它负责读取硬件上接收到的数据包并传送给上层协议,因此可能包含xxxinterrupt()和xxx_rx()函数,前者完成中断类型判断等基本工作,后者则需完成数据包的生成及将其递交给上层等复杂工作。

        对于特定的设备,我们还可以定义相关的私有数据和操作,并封装为一个私有信息结构体xxx_private,让其指针赋值给net_device的私有成员。在xxx_private结构体中可包含设备的特殊属性和操作、自旋锁与信号量、定时器以及统计信息等。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值