- 1、本文档共21页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Linux设备驱动之pci设备的枚举
一:前言 Pci,是Peripheral Component Interconnect的缩写,翻译成中文即为外部设备互联.与传统的总线相比.它的传输速率较高.能为用户提供动态查询pci deivce.和局部总线信息的方法,此外,它还能自动为总线提供仲裁.在近几年的发展过程中,被广泛应用于多种平台.pci协议比较复杂,关于它的详细说明请查阅有关pci规范的资料本文不会重复这些部份. 对于驱动工程师来说Pci设备的枚举是pci设备驱动编写最复杂的操作分析和理解这部份,是进行深入分析pci设备驱动架构的基础我们也顺便来研究一下,linux是怎么对这个庞然大物进行封装的二:pci架构概貌
上图展现了pci驱动架构中,pci_buspci_dev之间的关系如上图所示所有的根总线都链接在pci_root_buses链表中 Pci_bus -device链表链接着该总线下的所有设备而pci_bus-children链表链接着它的下层总线对于pci_dev来说pci_dev-bus指向它所属的pci_bus Pci_dev-bus_list链接在它所属bus的device链表上此外,所有pci设备都链接在pci_device链表中三:pci设备的配置空间 每个pci设备都有最多256个连续的配置空间配置空间中包含了设备的厂商ID,设备ID,IRQ,设备存储区信息等.摘下LDD3中的一副说明图,如下
要注意了,上图是以字节为单位的,而不是以位为单位. 那怎么去读取每个设备的配置空间呢我们在开篇的时候提到过,pci总线为用户提供了动态查询pci设备信息的方法在x86上,保留了0xCF8~0xCFF的8个寄存器.实际上就是对应地址为0xCF8的32位寄存器和地址为0xCFC的32位寄存器在0xCF8寄存中写入要访问设备对应的总线号, 设备号、功能号和寄存器号组成的一个32位数写入0xCF8.然后从0xCFC上就可以取出对应pci设备的信息.写入到0xCF8寄存器的格式如下低八位(0~7):??? (寄存器地址)0xFC.低二位为零 8~10:功能位.??? 有时候,一个pci设备对应多个功能.将每个功能单元分离出来,对应一个独立的pci device 11~15位:设备号??????? 对应该pci总线上的设备序号16~23位:总线号??????? 根总线的总线号为0.每遍历到下层总线,总线号+1 31:有效位??????????????????? 如果该位为1.则说明写入的数据有效,否则无效 例如:要读取n总线号m设备号f功能号对应设备的vendor id和Device id.过程如下:要写入到0xCF8中的数为: l = 0x8023 | n16 | m11 | f8 | 0x00 即:outl(l,0xCF8) 从0xCFC中读相关信息L = Inw(0xCFC)? (从上图中看到,vendor id和device id总共占四个字节.因此用inw) 所以device id = L0xFFVendor id = (L8)0xFF。
四:总线枚举入口分析 Pci的代码分为两个部份一个部份是与平台相关的部份存放在linux-2.6.25\arch\XXX\pci在x86,对应为linux-2.6.25\arch\x86\pci\? 另一个部份是平台无关的代码,存放在linux-2.6.25\driver\pci\下面大致浏览一下这两个地方的init函数.发现可能枚举pci设备是由函数pcibios_scan_root()完成的.不过有哪些信誉好的足球投注网站源代码后,发现有两个地方会调用这个调数.一个是在linux-2.6.25\arch\x86\pci\numa.c 另一个是linux-2.6.25\arch\x86\pci\Legacy.c 这两个地方都是封装在一个subsys_initcall()所引用的初始化函数呢? 到底哪一个文件才是我们要分析的呢? 分析一下linux-2.6.25\arch\x86\pci\下的Makefile_32.内容如下: obj-y???????????????????????????? := i386.o init.o ? obj-$(CONFIG_PCI_BIOS)???????????????? += pcbios.o obj-$(CONFIG_PCI_MMCONFIG)???? += mmconfig_32.o direct.o mmconfig-shared.o obj-$(CONFIG_PCI_DIRECT)? += direct.o ? pci-y???????????????????????????? := fixup.o pci-$(CONFIG_ACPI)?????????????????
文档评论(0)