从事linux C开发工作以来,工作内容主要是在应用层,对nginx和unbound等软件有些了解,也常对这2个软件进行二次开发。 对网络这块一直比较有兴趣。也很好奇网卡到底是怎么接受到报文的,以及报文如何被应用层所接受。自己在网上学习了一下,做个简单总结。 以飨后人。基本上我觉得分以下几个部分:

一、预备知识

1、PCI设备是有标准的,就是说PCI设备必须在固定位置包含公司、设备等信息,这样内核启动的时候读取出来,并保存在 struct pci_dev中。最终将所有PCI设备,组织成一个链表结构。

2、PCI标准中规定,PCI设备有一个配置区域,这些区域由BIOS在机器启动的时候,写入分配给该 PCI设备中断号,内存映射地址。因为由BIOS 统一分配,所有这些资源就不会重复。

二、网卡驱动初始过程

基本上了解内核模块怎么编写的人,应该了解rtl8139_init_module是在insmod命令模块加载的时候被调用的,它会调用pci_register_driver, 该函数是内核提供的,用来注册PCI设备驱动的。内核会遍历PCI设备链表,根据rtl8139_pci_tbl提供的信息,对比信息,如果满足,那么表明 这个驱动就是用来驱动这个设备的。一个设备只能有一个驱动,一个驱动可以驱动多个设备。

当给设备找到驱动以后,会调用pci_driver结构的 probe函数。也就是rtl8139_init_one函数。这个函数,就是会初始化设备,这块主要需要参考设备厂家的datasheet,操作各种寄存器。细节不讲了, 主要是让大家了解下大致,细节可以看一下代码。初始化的时候,dev->netdev_ops = &rtl8139_netdev_ops;,这就相当于注册了各种驱动处理函数了。 其中rtl8139_open在ifconfig eth0 up的时候会被调用,它会request_irq (dev->irq, rtl8139_interrupt, IRQF_SHARED, dev->name, dev);注册驱动。 dev-irq就是BIOS分配的。rtl8139_interrupt是中断处理函数。

三、网卡发送报文过程

发送的时候会调用 rtl8139_start_xmit。通过调用skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);,把报文写入ring buf, 也就是环形缓冲区,一般有4个。也就是说,发送的时候,就是把报文网ring buf中写,写满了就等下一次再发。

四、网卡接受报文过程

网上除了有发送缓冲区,也有接受缓冲区。当有报文来的时候,报文会被 DMA复制到缓冲区,然后发起中断。最终调用中断处理函数rtl8139_interrupt 他最终通过调用__napi_schedule(&tp->napi);把当前设备pool函数加入NAPI的链表中。也就rtl8139_poll函数。到目前为止,报文硬件中断处理就结束了。 那么肯定很好奇,报文还没被处理呢,只是放在缓冲区。其实就是通过中断下半部,也就是软中断soft irq来接受的。 下面继续:

软中断,算是一个内核进程,它没事处理的时候就挂起。它是可以被唤醒的。当它被唤醒的时候,它会执行net_rx_action,这个函数会遍历挂在 它上面的链表,也就是poll_list,也就是我们上面注册的rtl8139_poll。这个rtl8139_poll最终会调用rtl8139_rx来接受报文,而这个函数里面有个 while循环,就不停的从缓冲区中读取数据,并把数据填充到skb中,最终调用netif_receive_skb。来把报文往上送,这个函数呢,最终会根据不用的 协议调用相应的处理方法,如果是IP报文,最终会调用ip_rcv。之后,就会被送到应用层。具体的不是一下能讲完。后面有空再补充。

8139too.c网卡驱动简单分析的更多相关文章

  1. Linux网卡驱动架构分析

    一.网卡驱动架构 由上到下层次依次为:应用程序→系统调用接口→协议无关接口→网络协议栈→设备无关接口→设备驱动. 二.重要数据结构 1.Linux内核中每一个网卡由一个net_device结构来描述. ...

  2. DM9000网卡驱动深度分析

    一.dm9000_porbe函数分析 不同于u-boot代码,tq2440中的DM9000更加复杂,需要分析的点也很多: /* * Search DM9000 board, allocate spac ...

  3. [国嵌攻略][136][DM9000网卡驱动深度分析]

    网卡初始化 1.分配描述结构,alloc_etherdev 2.获取平台资源,platform_get_resource 2.1.在s3c_dm9k_resource中有相关的资源 2.2.add地址 ...

  4. LDD3 字符设备驱动简单分析

    最近在看LDD3,理解了一下,为了加深自己的印象,自己梳理一下.我用的CentOS release 6.6 (Final)系统. 一.编写编译内核模块的Makefile 以下是我用的Makefile ...

  5. Linux 网卡驱动设备程序设计(1)

    一.网卡驱动架构分析 1. Linux 网络子系统 #系统调用接口层 为应用程序提供访问网络子系统的统一方法. #协议无关层 提供通用的方法来使用传输层协议. #协议栈的实现 实现具体的网络协议 #设 ...

  6. Linux PCI网卡驱动的详细分析

    学习应该是一个先把问题简单化,在把问题复杂化的过程.一开始就着手处理复杂的问题,难免让人有心惊胆颤,捉襟见肘的感觉.读Linux网卡驱动也是一 样.那长长的源码夹杂着那些我们陌生的变量和符号,望而生畏 ...

  7. Linux网卡驱动移植--Dm9000网卡驱动分析

    1. Linux网络体系结构由以下5部分组成 ① 系统调用接口: 位于Linux网络子系统的顶部,为应用程序提供访问内核网络子系统的方法,主要指socket系统调用. ② 协议无关接口: 实现一组基于 ...

  8. 【Linux高级驱动】如何分析并移植网卡驱动

    dm9000的驱动分析 m9000_init platform_driver_register(); db); db); );  ; id_val ; id_val ; /* 获取芯片型号 */ id ...

  9. Xilinx Uboot网卡驱动分析

    1.MAC控制器.网卡.PHY.MDIO.mii.gmii.rgmii概念扫盲 网卡在功能上包含OSI模型的两个层,数据链路层和物理层.物理层定义了数据传送与接收所需要的电与光信号.线路状态.时钟基准 ...

随机推荐

  1. javascript创建跟随鼠标好玩的东西

    不说话,直接上代码. css: #createGoDivBox{ display: none; } #createGoDivBox div{ background-color: #00A6C2; po ...

  2. 【Alpha】Daily Scrum Meeting第三次

    本次随笔调换了展示顺序,把重要的内容放前面. 一.本次Daily Scrum Meeting主要内容 说明要完成alpha版本还需要哪些功能 对这些功能进行分析和实现方式的讨论 强调编码规范和变量命名 ...

  3. 简明 Git 命令速查表(中文版)

    原文引用地址:https://github.com/flyhigher139/Git-Cheat-Sheet/blob/master/Git%20Cheat%20Sheet-Zh.md在Github上 ...

  4. 《我爱背单词》 Alpha版 发布说明

    ——发布地址(baidu网盘) http://pan.baidu.com/s/15omtB ——简介  <我爱背单词>是一款英语单词记忆和管理辅助软件,旨在帮助广大考生在短期内攻克GRE. ...

  5. java并发编程(六)Runnable和Thread实现多线程的区别

    http://blog.csdn.net/ns_code/article/details/17161237

  6. PHP 学习笔记---基本语法

    ------php语言与JavaScript的使用 方法是相似 <script type="text/javascript"> </script>--js与 ...

  7. 【iCore3 双核心板_FPGA】实验二十六:SDRAM读写测试实验

    实验指导书及代码包下载: http://pan.baidu.com/s/1c1VRibY iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...

  8. js中==和===的区别

    ==用来判断值是否相等: ===用来判断值和类型是否相等

  9. ecmall源码中的 function _config_view()-关于重写

    ecmall中类库的继承过程: defaultAPP->MallbaseApp->FrontendApp->EcBaseApp->BaseApp->Object 在bas ...

  10. linq 小记

    1.简单的linq语法 //1 var ss = from r in db.Am_recProScheme select r; //2 var ss1 = db.Am_recProScheme; // ...