原创kylin_zeng:http://blog.csdn.net/kylin_fire_zeng  本文参考国嵌视频教程,再此感谢国嵌教育。

一、协议栈层次对比:

1)网络接口层把数据链路层和物理层合并在了一起,提供访问物理设备的驱动程序,对应的网络协议主要是以太网协议。
2)网络层协议管理离散的计算机间的数据传输,如IP协议为用户和远程计算机提供了信息包的传输方法,确保信息包能正确地到达目的机器。重要的网络层协议包括ARP(地址解析协议)、ICMP(Internet控制消息协议)和IP协议(网际协议)等
3)传输层的功能包括:格式化信息流、提供可靠传输。传输层包括TCP(Transmission Control Protocol,传输控制协议)和UDP(User Datagram Protocol,用户数据报协议),它们是传输层中最主要的协议
4)应用层位于协议栈的顶端,它的主要任务是服务于应用,如利用FTP(文件传输协议)传输一个文件。常见的应用层协议有:HTTP,FTP,Telnet等。应用层是Linux网络设定很关键的一层,Linux服务器的配置文档主要针对应用层中的协议

二、linux网络子系统
1)

2)Linux 网络子系统的顶部是系统调用接口层。它为用户空间的应用程序提供了一种访问内核网络子系
统的方法。位于其下面的是一个协议无关层,它提供了一种通用方法来使用传输层协议。然后是具体
协议的实现,在Linux 中包括内嵌的协议TCP、UDP,当然还有IP。然后是设备无关层,它提供了
协议与设备驱动通信的通用接口,最下面是设备驱动程序。

3)系统调用接口:为应用程序提供访问内核网络子系统的方法:Socket系统调用。
4)协议无关接口:实现一组通用函数来访问各种不同的协议:通过socket实现。Linux 中的socket 使用
struct sock来描述,这个结构包含了特定socket 所需要的所有状态信息,还包括
socket 所使用的特定协议和在socket 上可以执行的一些操作

5)网络协议层用于实现各种具体的网络协议,如:TCP、UDP 等
6)设备无关接口:设备无关接口将协议与各种网络设备驱动连接在一起。
这一层提供一组通用函数供底层网络设备驱动程序使用,让它们可以对高层协议栈进行操作。首先,设备驱
动程序可能会通过调用register_netdevice 或unregister_netdevice 在内核中进行注册或注销。调
用者首先填写net_device 结构,然后传递这个结构进行注册。内核调用它的init 函数(如果定义了这种函
数),然后执行一组健全性检查,并将新设备添加到设备列表中(内核中的活动设备链表)
要从协议层向设备发送数据,需要使用dev_queue_xmit函数,这个函数对数据进行排
队,并交由底层设备驱动程序进行最终传输报文的接收通常是使用netif_rx执行的。当底层设备驱动
程序接收到一个报文(包含在所分配的sk_buff 中)时,就会通过调用netif_rx 将数据上传至设备
无关层,然后,这个函数通过netif_rx_schedule 将sk_buff 在上层协议队列中进行排队,供以后进行处理。

7)驱动程序:网络体系结构的最底部是负责管理物理网络设备的设备驱动程序层

****************************************************************************************************************************************

二、网络驱动程序设计:
每个网络接口都由一个net_device结构来描述,该结构可使用如下内核函数动态分配:
1、struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *))
   sizeof_priv 私有数据区大小;mask:设备名;setup 初始化函数
  
2、struct net_device *alloc_etherdev(int sizeof_priv)

struct net_device
  {
   char name[IFNAMSIZ] ;//   设备名,如:eth%d  //%d表示由内核自动获取。
   vunsigned long state ;//   设备状态
   vunsigned long base_addr ;//   I/O 基地址
   vunsigned int irq ;//   中断号
      ...
  }
 
3、net_device初始化:int (*init)(struct net_device *dev)
   初始化函数。该函数在register_netdev时被调用来完成对net_device 结构的初始化
  
   net_device和字符驱动一样, 网络设备也要声明能操作它的函数。有些操作可以保留为NULL, 有的可以通过ether_setup 来使用默认设置。网络
接口的设备方法可分为两组:基本的和可选的,基本方法包括那些使用接口所必需的;可选的方法实现更多高级的功能。

4、基本方法:
   int (*open)(struct net_device *dev) //打开接口。ifconfig 激活时,接口将被打开。
   int (*stop)(struct net_device *dev)  //停止接口。该什么时候调用呢?
   int (*hard_start_xmit) (struct sk_buff *skb, struct net_device *dev) //数据发送函数。
  
5、可选操作:
   int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd) //处理特定于接口的ioctl 命令
   int (*set_mac_address)(struct net_device *dev, void *addr) //改变Mac地址的函数,需要硬件支持该功能
  
6、设备注册:
   网络接口驱动的注册方式与字符驱动不同之处在于它没有主次设备号,并使用如下函数注册。
   int register_netdev(struct net_device *dev)  
  
7、sk_buff 存放网络包:
    Linux内核中的每个网络数据包都由一个套接字缓冲区结构struct sk_buff 描述,即一个
    sk_buff结构就是一个包,指向sk_buff的指针通常被称做skb。
    struct sk_buff
    {
    struct device *dev;  //处理该包的设备
    __u32 saddr; //IP源地址
    __u32 daddr; //IP目的地址
    __u32 raddr; //IP路由器地址     
    
    unsigned char *head;    //分配空间的开始
    unsigned char *data;     //有效数据的开始
    unsigned char *tail;       //有效数据的结束
    unsigned char *end;     //分配空间的结束
    unsigned long len; //有效数据的长度
    
    };
   
8、skb操作函数:
   操作sk_buff的内核函数如下: struct sk_buff *alloc_skb(unsigned int len, int priority)
   分配一个sk_buff 结构,供协议栈代码使用 struct sk_buff *dev_alloc_skb(unsigned int len)分配一个sk_buff 结构,供驱动代码使用
  
   unsigned char *skb_push(struct sk_buff *skb, int len) //向后移动skb的tail指针,并返回tail移动之前的值。  这样才能再填入后面的值
   unsigned char *skb_put(struct sk_buff *skb, int len) //向前移动skb的head指针,并返回head移动之后的值     这样才不会覆盖后面的值
   kfree_skb(struct sk_buff *skb)  //释放一个sk_buff 结构,供协议栈代码使用
   dev_kfree_skb(struct sk_buff *skb) //释放一个sk_buff 结构,供驱动代码使用
  
9、设备打开:
    Open 请求任何它需要的系统资源并且启动
    接口:
    注册中断,DMA等
    设置寄存器,启动设备
    启动发送队列
   
    例如:
    int net_open(struct net_device *dev)
  {
    /*申请中断*/
    request_irq(dev->irq, &net_interrupt, SA_SHIRQ,
    “dm9000”, dev);
    /* 设置寄存器,启动设备*/
    ...... ...... ...... ......
    /*启动发送队列*/
    netif_start_queue(dev);
  }
   
10、数据发送:
    当核心需要发送一个数据包时,它调用hard_start_transmit函数,该函数将最终调用到net_device结构中的hard_start_xmit函数指针。
11、数据接收
    网络接口驱动可以实现两种方式的报文接收: 中断和查询,Linux中驱动多采用中断方式   
   
    接收流程:
    1、分配Skb: 
       skb = dev_alloc_skb(pkt->datalen + 2)
  2、从硬件中读取数据到Skb
  3、调用netif_rx将数据交给协议栈
     netif_rx(skb)
  
12、中断处理:
  网络接口通常支持3种类型的中断: 新报文到达中断、报文发送完成中断和出错中断。中
  断处理程序可通过查看网卡中的中断状态寄存器,来分辨出中断类型。

linux网络体系架构的更多相关文章

  1. Linux网络驱动架构

    网络设备介绍 网络设备是计算机体系结构中必不可少的一部分,处理器如果想与外界通信,通常都会选择网络设备作为通信接口.众所周知,在 OSI(Open Systems Interconnection,开放 ...

  2. Linux网络编程学习(一) ----- 概论和Linux模型(第一章第二章)

    1.什么是计算机网络,通信方式是什么? 计算机网络就是通过通信线路相互连接的计算机的集合,主要通过双绞线.同轴电缆.电话线或者光缆等有形传输介质通信,还有就是通过激光.微波.卫星等实现无线通信 2.W ...

  3. 【转】XenServer体系架构解析

    XenServer是一套已在云计算环境中经过验证的企业级开放式服务器虚拟化解决方案,可以将静态.复杂的IT环境转变为更加动态.易于管理的虚拟数据中心,从而大大降低数据中心成本.同时,它可以提供先进的管 ...

  4. Linux网络编程&内核学习

    c语言: 基础篇 1.<写给大家看的C语言书(第2版)> 原书名: Absolute Beginner's Guide to C (2nd Edition) 原出版社: Sams 作者: ...

  5. ocp11g培训内部教材_052课堂笔记(042)_体系架构

    OCP 052 课堂笔记 目录 第一部分: Oracle体系架构... 4 第一章:实例与数据库... 4 1.Oracle 网络架构及应用环境... 4 2.Oracle 体系结构... 4 3. ...

  6. [转]OpenContrail 体系架构文档

    OpenContrail 体系架构文档 英文原文:http://opencontrail.org/opencontrail-architecture-documentation/ 翻译者:@KkBLu ...

  7. 精通android体系架构、mvc、常见的设计模式、控制反转(ioc)

    1.请看某个著名的it公司一则招聘信息的其中一条要求:“熟悉android系统架构及相关技术,1年以上实际android平台开发经验:”,里面非常明确的说道要求熟练android系统架构,这从某种程度 ...

  8. 【转帖】Linux 内核系统架构

    Linux 内核系统架构   描述Linux内核的文章已经有上亿字了 但是对于初学者,还是应该多学习多看,毕竟上亿字不能一下子就明白的. 即使看了所有的Linux 内核文章,估计也还不是很明白,这时候 ...

  9. Android四层体系架构

    Application应用层 应用是用Java语言编写的运行在虚拟机上的程序,即图中最上层的蓝色部分.手机的上层应用其实,Google最开始时就在Android系统中捆绑了一些核心应用比如e-mail ...

随机推荐

  1. easyui好例子,值得借鉴

    http://www.cnblogs.com/wuhuacong/p/3317223.html

  2. java中printf中用法详解

    目前printf支持以下格式: %c 单个字符 %d 十进制整数 %f 十进制浮点数 %o 八进制数 %s 字符串 %u 无符号十进制数 %x 十六进制数 %% 输出百分号% printf的格式控制的 ...

  3. shell实例浅谈之六文件特定行打印的多种方法

    一.问题 Sed和AWK在处理文件方面有很强的优势,还有head和tail等文件处理工具的使用,grep也可实现文本的搜索.上述命令都可以在后面直接加文件名,不需要在前面使用cat添加管道,cat会影 ...

  4. net core 静态文件

    asp.net core 之静态文件目录的操作   文章前言 之前写了一篇关于模拟登录的文章,自我感觉内容不太丰富,今天的这篇文章,希望在内容上能丰富些.本人缺少写文章的经验,技术上也是新手,但我会努 ...

  5. VS QT 配置OpenGL

    在visual studio 下编译OpenGL代码出现以下错误,原因是vs没有自带opengl库,需要自己引入 无法解析的外部符号 __imp__glClear@4 无法解析的外部符号 __imp_ ...

  6. stackoverflow,stackexchange,zhihu,ilewen,segmentfault,answerhub,question2answer,,

    http://stackexchange.com/ http://question2answer.org/ http://answerhub.com/qa/ http://segmentfault.c ...

  7. F#实现的单链表(函数式的思想)

    // 在 http://fsharp.net 上了解有关 F# 的更多信息 // 请参阅“F# 教程”项目以获取更多帮助. type list = | Nil | Cons of int * list ...

  8. POJ 3691 &amp; HDU 2457 DNA repair (AC自己主动机,DP)

    http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...

  9. 公共 DNS server IP 地址

    公共 DNS server IP 地址 名称 DNS server IP 地址 CNNIC SDNS 1.2.4.8 210.2.4.8 114 DNS 114.114.114.114 114.114 ...

  10. 深度学习大牛Yoshua Bengio

    深度学习大牛Yoshua Bengio今天AAAI四小时深度学习教学讲座非常详尽,PPT有230页:http://t.cn/zQ4VRVx 如觉太长,可看他33页综述文:http://t.cn/zjk ...