
学习应该是首先简化问题并使问题复杂化的过程. 从一开始就处理复杂的问题,人们不可避免地会感到恐惧和紧张. 读取Linux网卡驱动程序也是如此. 长长的源代码与我们不熟悉的变量和符号混合在一起. 不用担心,总有解决方案. 首先,剪切一些我们无法控制的代码,保留必要的部分,然后掌握框架. 任何其他事情自然都会结束. 这是作者的经验.
通常,使用的Linux网卡驱动程序代码约为3000行. 毫无疑问,代码量和表达的知识量是巨大的. 有什么办法可以缩短这段代码的数量,使我们的学习变得更轻松?但是,在作者的不懈努力下,网络设备在仍可以正常工作的前提下减少到600多条线路. 我们将首先删除尚不可用的功能. 这样,事情变得简单得多,实际上只剩下一帧. 下面我们将分析这个可执行框架.
由于篇幅所限,在下面的分析中,我不会列出内核中涉及的所有功能代码,但是我会给您具体的文件,请您自己阅读.
首先,让我们看一下设备的初始化. 正确编译程序后,需要将生成的目标文件加载到内核中. 我们将先关闭ifconfig eth0并使用rmmod 8139too卸载正在使用的网卡驱动程序,然后再使用insmod 8139too.o驱动我们的驱动程序. 将其加载到其中(其中8139too.o是我们编译的目标文件). 就像C程序具有main函数main()一样,模块也具有要执行的第一个函数,即module_init(rtl8139_init_module);在我们的程序中,rtl8139_init_module()在insmod之后首先执行,其代码如下:
static int __init rtl8139_init_module(void)

{
返回pci_module_init(&rtl8139_pci_driver);
}
它直接调用pci_module_init(),功能代码在Linux / drivers / net / eepro100.c中,并传递rtl8139_pci_driver(此结构在我们的驱动程序代码中定义,它是驱动程序与PCI设备联系的链接)作为参数. rtl8139_pci_driver的定义如下:
静态结构pci_driver rtl8139_pci_driver = {

名称: MODNAME,
id_table: rtl8139_pci_tbl,
探针: rtl8139_init_one
删除: rtl8139_remove_one,
};

pci_module_init()未在驱动程序代码中定义,您必须已经认为它是Linux内核提供给模块的标准接口,因此该接口的作用,作者跟踪了此功能. 它调用pci_register_driver(),功能代码在Linux / drivers / pci / pci.c中,pci_register_driver要做三件事.
①注册参数rtl8139_pci_driver已在内核中注册. 内核中有一个很大的PCI设备链接列表. 在这里,要挂起此PCI驱动程序.
②检查总线上所有PCI设备的配置空间(NIC设备是一种PCI设备). 如果发现标识信息与rtl8139_pci_driver中的id_table相同,即rtl8139_pci_tbl网卡驱动代码,则其定义如下:
静态结构pci_device_id rtl8139_pci_tbl [] __devinitdata = {
{0x10ec,0x8129,PCI_ANY_ID,PCI_ANY_ID,0、0、1},

{PCI_ANY_ID,0x8139,0x10ec,0x8139,0,0,0},
{0,}
};
然后使用驱动程序来驱动设备,因此rtl8139_pci_driver中的探测功能称为rtl8139_init_one,该函数在我们的驱动程序中定义,用于初始化整个设备并做好一些准备工作. 这里应该注意,pci_device_id是内核定义的结构网卡驱动代码,用于区分不同的PCI设备. 例如,在我们的案例中,0x10ec代表Realtek. 我们扫描PCI设备配置空间. 如果找到由Realtek制造的设备,则两者是正确的. 继续当然,在匹配公司编号之后,您必须查看其他设备编号,依此类推. 它仅表明该驱动程序可以为该设备提供服务.
③rtl8139_pci_driver结构挂在该设备的数据结构(pci_dev)上,表明此后该设备具有其自己的驱动程序. 驱动程序已经找到了它服务的对象.
PCI是总线标准. PCI总线上的设备是PCI设备. 这些设备有很多类型,包括网卡设备. 每个PCI设备都在内核中抽象为数据结构pci_dev. 它描述了PCI设备. 有关的所有功能,请参阅相关文档以获取详细信息. 本文篇幅有限,无法详细描述. 但是,在许多地方与驾驶员的关系尤为重要,必须加以说明. PCI设备均符合PCI标准. 此部分中的所有PCI设备均相同. 每个PCI设备都有一个寄存器来存储配置空间. 这部分的格式是相同的. 例如,第一个寄存器始终是制造商编号,例如Realtek是10ec,而Intel是另一个编号. 这些都是来自标准组织等商家的应用程序. 他们绝对不同. 我可以通过配置空间识别制造商和设备编号. 无论您使用的是x86还是ppc平台,它们都是相同的标准格式. 当然,这些PCI配置空间的统一格式是不够的. 例如,人类有鼻子和眼睛,但不是每个人都有相同的鼻子和眼睛. 网卡设备是PCI设备,必须遵守规则. PCI配置空间已集成在设备中,但必须与可以控制网卡作为网卡工作的寄存器集成. 访问寄存器成为一个问题. 在Linux中,我们将这些寄存器映射到主内存虚拟空间. 换句话说,我们的CPU访问指令可以访问设备中的这些控制寄存器. 综上所述,PCI设备主要包括两种类型的空间,一种是配置空间,这是一种由操作系统或BIOS控制的统一格式的空间. 无法访问CPU指令. 访问此空间取决于BIOS功能. 实际上,Linux访问配置空间该功能是通过CPU指令来驱动BIOS以完成读写访问. 另一种类型是普通控制寄存器空间. 映射此部分后,CPU可以访问以控制设备的工作.
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-186788-1.html
现在能有6000多吨的052D相陪已经是不容易啦
高铁坐吗