Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1886738
  • 博文数量: 496
  • 博客积分: 12043
  • 博客等级: 上将
  • 技术积分: 4778
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-27 14:26
文章分类

全部博文(496)

文章存档

2014年(8)

2013年(4)

2012年(181)

2011年(303)

2010年(3)

分类: 嵌入式

2012-09-25 11:36:58

源码:linux-2.6.32.2
网卡 :DM9000

          利用了两天的时间看了linux的网卡驱动,主要分析了以下问题:
          1、用户接口函数在什么地方?
          2、应用层如何操作DM9000?整个流程是什么?
          
          linux网卡驱动——硬件层-用户层 - 边缘之火 - 边缘之火
                                图1

首先看图1 ,在用户空间要操作硬件,需要通过系统调用转到内核空间,linux中有三种设备文件:字符设备、块设备和套接字。其实套接字也不能叫做文件了,至于它到底是什么不去讨论。
看这句来自ifconfig源码中 sockets_open函数中的一句
         af->fd = socket(af->af, type, 0);
        af->fd 这个应该有点熟悉吧,我们在操作设备时打开一个设备文件要用fd保存文件号,这里也一样;这里的socket是类似open,write的系统调用函数,当然对于网络设备,还有其他好多的系统调用,例如:bind 、connect、listen等等。这里我们重点分析一下socket到底做了什么?还是用图吧!看图2.
linux网卡驱动——硬件层-用户层 - 边缘之火 - 边缘之火
 

图2
          
   
这张图就是socket做的主要工作了,我们得到的af->fd就是图中file的文件号了,而socket作为了file的private_data,但是要注意虽然我们似乎有了一个文件,这个文件却不是我们的重点,真正的重点是socket,它才是linux网卡设备的关键。

好了,到这里在看看第一个问题能否回答——  用户接口函数在什么地方?回想普通的设备文件,当我们使用open系统调用时,我们不考虑中间做了什么,我们一定知道open系统调用一定使用我们在file_operations中实现的open函数。很直接,用户层直接到硬件层,这样作为一个驱动开发者只要关心open函数怎么实现就行了,但是在来看看网卡的驱动,似乎不是那么简单,谁也不会告诉你socket系统调用对应着硬件层的什么函数......这样我们要重新认识一下网卡驱动了。这也是下面这图为什么存在的原因.。

linux 网络设备的分层模型:
 
linux网卡驱动——硬件层-用户层 - 边缘之火 - 边缘之火
                                              图3
图3是linux系统网络设备的分层模型,现在来看 socket是在system call interface 之上了,离设备驱动还有4层,接下来我们看下用户如何能操作到硬件:

在DM9000的驱动中我们注册了这么一个函数集
static const struct net_device_ops dm9000_netdev_ops = {
.ndo_open = dm9000_open,
.ndo_stop = dm9000_stop,
.ndo_start_xmit = dm9000_start_xmit,
.ndo_tx_timeout = dm9000_timeout,
.ndo_set_multicast_list = dm9000_hash_table,
.ndo_do_ioctl = dm9000_ioctl,
.ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = eth_mac_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = dm9000_poll_controller,
#endif
};

.ndo_start_xmit = dm9000_start_xmit,是需要驱动开发者写的,这个函数是个发送函数,直接操作硬件,那么就来看看用户如何操作到它。
为此,我转载网上一张图片           
linux网卡驱动——硬件层-用户层 - 边缘之火 - 边缘之火
 
这张图很形象的说明了数据发送的整个过程,要注意的就是各层的接口函数:

 从上到下依次为 sock_sendmsg、 inet_sendmsg 、 tcp_transmit_skb 、ip_queue_xmit、 neigh_resolve_output、 dev_queue_xmit

还有接受,硬件层是用中断来接受的:图同样来至

 linux网卡驱动——硬件层-用户层 - 边缘之火 - 边缘之火
 各层的接口函数:从下到上,netif_rx 、 ip_rcv ip_local_deliver_finish 、tcp_v4_rcv、 inet_recvmsg 、sock_recvmsg。
阅读(1667) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~