8139too.c网卡驱动简单分析

从事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。之后,就会被送到应用层。具体的不是一下能讲完。后面有空再补充。

时间: 2024-08-02 02:24:23

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

Linux网卡驱动架构分析

一.网卡驱动架构 由上到下层次依次为:应用程序→系统调用接口→协议无关接口→网络协议栈→设备无关接口→设备驱动. 二.重要数据结构 1.Linux内核中每一个网卡由一个net_device结构来描述. 2.网卡操作函数集:net_device_ops,这个数据结构是上面net_device的一个成员. 3.网络数据包:sk_buff. 三.网卡驱动代码分析 所用文件为cs89x0.c,主要分析三个部分:网卡初始化.发送数据.接收数据. ㈠网卡初始化 网卡驱动初始化主要在函数init_module

[国嵌攻略][133][网卡驱动架构分析]

Linux网络子系统 1.系统调用接口:提供系统调用 2.协议无关接口:统一网络协议给系统调用接口使用 3.网络协议栈  :实现网络协议 4.设备无关接口:统一设备驱动程序给网络协议使用 5.设备驱动程序:实现网卡驱动 Linux驱动在内核中都有一个结构来描述,首先找到设备描述结构,然后找到设备如何注册和初始化. 网卡描述结构 在Linux内核中,每个网卡都由一个net_device结构来描述,其中一些重要成员: char name[IFNAMSIZ]   设备名,如:eth%d unsigne

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

网卡初始化 1.分配描述结构,alloc_etherdev 2.获取平台资源,platform_get_resource 2.1.在s3c_dm9k_resource中有相关的资源 2.2.add地址由CS4和ADD2决定,是20000000 2.3.dat地址由CS4和ADD2决定,是20000004 2.4.中断资源是EINT7 3.虚拟地址映射,ioremap 4.读取芯片类型 5.设置操作函数集 6.读取MAC地址 7.注册网卡驱动,register_netdev 8.启动发送队列,ne

LDD3 字符设备驱动简单分析

最近在看LDD3,理解了一下,为了加深自己的印象,自己梳理一下.我用的CentOS release 6.6 (Final)系统. 一.编写编译内核模块的Makefile 以下是我用的Makefile ifneq ($(KERNELRELEASE),) # 第一次被调用时,KERNELRELEASE为空,所以不会被执行 obj-m := scull.o else # 将内核编译用的Makefile路径赋值给KERNELRELEASE KERNELRELEASE ?= /lib/modules/`u

网卡驱动设计---架构分析加回环网卡驱动设计(网卡驱动上)

网卡驱动架构分析: 1. Linux网络子系统 2. 重要数据结构 总结一下三个重要的数据结构: 2.1. net_device 2.2. net_device_ops 2.3. sk_buff 3. 网卡驱动架构分析 CS8900.c //早期2410使用的网卡芯片 3.1. 网卡初始化 首先找到驱动程序的入口: 早期的驱动入口并不是module_init()函数,而是init_module,所以找到这个函数 int __init init_module(void) { struct net_

回环网卡驱动设计

回环网卡是一个虚拟网卡,当上层协议栈发出包后,包又会被发回给上层协议栈.下面来编程实现回环网卡驱动. 所需头文件 #include <linux/kernel.h> #include <linux/jiffies.h> #include <linux/module.h> #include <linux/interrupt.h> #include <linux/fs.h> #include <linux/types.h> #includ

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

一.网卡驱动架构分析 1. Linux 网络子系统 #系统调用接口层 为应用程序提供访问网络子系统的统一方法. #协议无关层 提供通用的方法来使用传输层协议. #协议栈的实现 实现具体的网络协议 #设备无关层 协议与设备驱动之前通信的通用接口 #设备驱动程序 2. 重要数据结构 2.1 网卡描述结构 在Linux内核中,每个网卡都由一个<net_device>结构来描述,其中的一些重要成员有: #char name[IFNAMSIZ] 设备名,如:eth%d #unsigned long ba

netback的tasklet调度问题及网卡丢包的简单分析

最近在万兆网卡上测试,出现了之前千兆网卡没有出现的一个现象,tasklet版本的netback下,vm进行发包测试,发现vif的interrupt默认绑定在cpu0上,但是vm发包运行时发现host上面cpu1, cpu2的ksoftirqd很高. 从之前的理解上来说,包从netfront出来通过eventchannel notify触发vif的irq处理函数,然后tasklet_schedule调用tx_action,通过一系列处理流程把包发给网卡.所以vif的interrupt绑在哪个cpu

PCI驱动框架简单分析

一.PCI 概念介绍 PCI是CPU和外围设备通信的高速传输总线.PCI规范能够实现32位并行数据传输,工作频率为 33MHz 或 66MHz ,最大吞吐率高达266MB/s,PCI的衍生物包括 CardBus.mini-PCI.PCI-Express.cPCI等. PCI总线体系结构是一种层次式的体系结构.在这种层次体系结构中,PCI桥设备占据着重要的地位,它将父总线与子总线连接在一起,从而使整个系统看起来像一个倒置的树状结构,树的顶端是CPU,它通过一个较为特殊的CPI桥设备-Host/PC