网络设备驱动 和 DM9000 驱动程序分析
网络设备驱动 和 DM9000 驱动程序分析
分析内核版本:Linux 2.6.36.2。 分析网卡:DM9000
一、网络设备驱动程序分析。
1、Linux 网络设备驱动程序 分层:
Linux 网络设备驱动程序从上到下可分为4层,依次为:网络协议接口层、网络设备接口层、提供实际功能的设备 驱动功能层、以及 网络设备与媒介层。这4层作用如下:
1) 网络协议接口层:网络协议接口层想网络协议提供统一的数据包收发接口,不论是上层ARP,还是IP,都通过dev_queue_xmit() 函数收发数据,并通过netif_rx 函数
接收数据。这一层的存在使得上层协议独立于具体的设备。
2)网络设备接口层:网络设备接口层向协议层接口层提供统一的用于描述具体网络设备属性 和 操作的结构体 net_device,该结构体是设备驱动功能层中各函数的容器,
实际上,网络设备接口层从宏观上规划了具体操作硬件的设备驱动功能层的结构。
3)设备功能层:该层的各个函数是网络设备接口层net_device 数据结构具体成员,是驱使网络设备硬件完成相应动作的程序,它通过har_start_xmit() 函数启动发送操作,
并通过网络设备上的中断触发接收操作。
4)网络设备 与 媒介层: 是完成数据包发送和接收的物理实体,包括网络适配器和具体的传输媒介,网络适配器被设备驱动功能层中的函数物理上驱动,对于Linux而言,
网络设备和媒介都是可以虚拟的。
在设计具体的网络设备驱动程序是,我们需要完成的主要工作是编写设备驱动功能层 的 相关函数以以填充net_device 数据结构的内容并将net_device 注册入内核。
2、网络协议接口层程序分析:
1) int netif_xmit (struct sk_buff *skb);// 发送一个sk_buff 数据包
int netif_rx (struct sk_buff *skb); // 接收一个数据包
以上函数定义在 net/core/dev.c 中
sk_buff 结构体定义在 include/linux/skbuff.h 文件, 它的含义为“套接字缓冲区”,用于在Linux 网络子系统中个层之间传递数据,是Linux 网络子系统数据传递的“中枢神经”
2) 套接字缓冲区 sk_buff 结构体
- struct sk_buff {
- /* These two members must be first. */
- struct sk_buff *next;
- struct sk_buff *prev;
- ktime_t tstamp;
- struct sock *sk;
- struct net_device *dev;
- /*
- * This is the control buffer. It is free to use for every
- * layer. Please put your private variables there. If you
- * want to keep them across layers you have to do a skb_clone()
- * first. This is owned by whoever has the skb queued ATM.
- */
- char cb[48] __aligned(8);
- unsigned long _skb_refdst;
- #ifdef CONFIG_XFRM
- struct sec_path *sp;
- #endif
- unsigned int len,
- data_len;
- __u16 mac_len,
- hdr_len;
- union {
- __wsum csum;
- struct {
- __u16 csum_start;
- __u16 csum_offset;
- };
- };
- __u32 priority;
- kmemcheck_bitfield_begin(flags1);
- __u8 local_df:1,
- cloned:1,
- ip_summed:2,
- nohdr:1,
- nfctinfo:3;
- __u8 pkt_type:3,
- fclone:2,
- ipvs_property:1,
- peeked:1,
- nf_trace:1;
- kmemcheck_bitfield_end(flags1);
- __be16 protocol;
- void (*destructor)(struct sk_buff *skb);
- #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
- struct nf_conntrack *nfct;
- struct sk_buff *nfct_reasm;
- #endif
- #ifdef CONFIG_BRIDGE_NETFILTER
- struct nf_bridge_info *nf_bridge;
- #endif
- int skb_iif;
- #ifdef CONFIG_NET_SCHED
- __u16 tc_index; /* traffic control index */
- #ifdef CONFIG_NET_CLS_ACT
- __u16 tc_verd; /* traffic control verdict */
- #endif
- #endif
- __u32 rxhash;
- kmemcheck_bitfield_begin(flags2);
- __u16 queue_mapping:16;
- #ifdef CONFIG_IPV6_NDISC_NODETYPE
- __u8 ndisc_nodetype:2,
- deliver_no_wcard:1;
- #else
- __u8 deliver_no_wcard:1;
- #endif
- kmemcheck_bitfield_end(flags2);
- /* 0/14 bit hole */
- #ifdef CONFIG_NET_DMA
- dma_cookie_t dma_cookie;
- #endif
- #ifdef CONFIG_NETWORK_SECMARK
- __u32 secmark;
- #endif
- union {
- __u32 mark;
- __u32 dropcount;
- };
- __u16 vlan_tci;
- sk_buff_data_t transport_header; // 传输层
- sk_buff_data_t network_header; // 网络层
- sk_buff_data_t mac_header; // MAC 层
- /* 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;
- };
|
评论暂时关闭