|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
初学阶段只要把上课时候学习过的命令练熟就可以了.单靠学习各种命令而成为高手是不可能的。
进修应当是一个先把成绩复杂化,再把成绩庞大化的历程。一入手下手就动手处置庞大的成绩,不免让人故意惊胆颤,左支右绌的感到。读Linux网卡驱动也是一样。那长长的源码同化着那些我们生疏的变量和标记,望而却步即是天经地义的了。不要忧虑,事变总有办理的举措,先把一些我们管不着的代码切割进来,留下必需的部分,把框架把握了,那其他的事变天然就瓜熟蒂落了,这是笔者的心得。
一样平常在利用的Linux网卡驱动代码动辄3000行摆布,这个代码量和它所表达出来的常识量无疑是复杂的,我们有无举措延长一下这个代码量,使我们的进修变的复杂些呢?经由笔者的不懈勉力,在仍旧可以使收集设备一般事情的条件下,把它缩减到了600多行,我们把临时还用不上的功效先割进来。如许一来,事变就复杂多了,真的就剩下一个框架了。
上面我们就来分析这个能够实行的框架。
限于篇幅,以下剖析用到的一切触及到内核中的函数代码,我都不予列出,但给出在哪一个详细文件中,请读者自行查阅。
起首,我们来看看设备的初始化。当我们准确编译完我们的程序后,我们就必要把天生的方针文件加载到内核中往,我们会先ifconfigeth0down和rmmod8139too来卸载正在利用的网卡驱动,然后insmod8139too.o把我们的驱动加载出来(个中8139too.o是我们编译天生的方针文件)。就像C程序有主函数main()一样,模块也有第一个实行的函数,即module_init(rtl8139_init_module);在我们的程序中,rtl8139_init_module()在insmod以后首先实行,它的代码以下:
staticint__initrtl8139_init_module(void)
{
returnpci_module_init(&rtl8139_pci_driver);
}
它间接挪用了pci_module_init(),这个函数代码在Linux/drivers/net/eepro100.c中,而且把rtl8139_pci_driver(这个布局是在我们的驱动代码里界说的,它是驱动程序和PCI设备接洽的纽带)的地点作为参数传给了它。rtl8139_pci_driver界说以下:
staticstructpci_driverrtl8139_pci_driver={
name:MODNAME,
id_table:rtl8139_pci_tbl,
probe:rtl8139_init_one,
remove:rtl8139_remove_one,
};
pci_module_init()在驱动代码里没有界说,你必定想到了,它是Linux内核供应给模块是一个尺度接口,那末这个接口都干了些甚么?笔者跟踪了这个函数,内里挪用了pci_register_driver(),这个函数代码在Linux/drivers/pci/pci.c中,pci_register_driver做了三件事变。
①是把带过去的参数rtl8139_pci_driver在内核中举行了注册。内核中有一个PCI设备的年夜的链表,这里卖力把这个PCI驱动挂到内里往。
②是检察总线上一切PCI设备(网卡设备属于PCI设备的一种)的设置空间,假如发明标识信息与rtl8139_pci_driver中的id_table不异,即rtl8139_pci_tbl,而它的界说以下:
staticstructpci_device_idrtl8139_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中的probe函数即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能够会见来把持设备事情。
如今我们回到下面pci_register_driver的第二步,假如找到相干设备和我们的pci_device_id布局数
12345下一页
每一个开发团队都对他的发行版做过测试后放出的.那些国际知名的大品牌更是如此。 |
|