LinuxKernel核心中文手册PCI_第1页
LinuxKernel核心中文手册PCI_第2页
LinuxKernel核心中文手册PCI_第3页
LinuxKernel核心中文手册PCI_第4页
LinuxKernel核心中文手册PCI_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

PeripheralComponentInterconnect〔PCI化和可掌握的方式把系统中的外设组件连接起来的一个标准。标准的PCILocalBus标准描述了系统组件电气连接的方法和它们行为的方法。本章探讨LinuxPCI总线和设备。6.1PCIPCIPCI-PCI桥〔bridge〕是系统组件联系在一起的粘合剂。CUPvideo设备连在主要的PCI总线,PCI总线0。一个特别的PCI设PCI-PCIPCIPCI1。依据PCIPCI1描PCI-PCIPCI0PCISCSI和以太网设备。物理上桥、次要PCI总线和这两种设备可以在同一块PCI卡上。系统中的PCI-ISA桥ISA设备,本图显示了一个超级I/O掌握芯片,掌握键盘、鼠标和软驱。PCIAddressSpace〔PCI地址空间〕CPUPCI设备需要访问它们所共享的内存PCI设备并在它们之间传递信息。一般地共享的内存包括设备的掌握和状态存放器。这些存放器用于掌握设备和PCISCSISCSI设备的状态存放器,推断它是否可SCSI磁盘写一块信息。或者它可以写入掌握存放器让它关闭的设备开头运行。CPU的使用的系统内存可以用作这种共享内存,但是假设这样的话,每一次 PCI设备访问内存,CPU都不得不停顿,等待PCI设备完成。对于内存的访问通常有限制,同一时间只能有一个系统组件允许访问。这会使得系统速度降低。允许系统的外部设备在一个不受控的方式下访问主内存也不是一个好方法。这会格外危急:一个恶意的设备会让系统格外不稳定。外部设备由它们自己的内存空间。CPU可以访问这些空间,但是设备对于系统内存的访问受到DMA〔DirectMemoryAccess直接内存存取〕通道ISA设备可以访问两ISAI/O〔/输出〕和ISAPCIPCII/OPCIPCI配置空间〔configurationspaceCPU可以访问全部的地址空间其中PCII/OPCI内存地址空间由PCILinuxPCI初始化代码使用。AlphaAXP持芯片来访问象PCI配置空间这样的其他地址空间。它使用了一个地址空间的映射方案,从巨大的虚拟地址空间中偷出一局部映射到PCI地址空间。PCIConfigurationHeaders〔PCI配置头〕系统中的每一个PCI设备,包括PCI-PCI桥都由一个配置数据构造,位于PCI配置地址空间中。PCIPCI配置地址空间的精准位置依靠于设备PCIPCPCIPCI显示卡配置头会在一个位置,而假设它被插到另一个PCI槽位则它的头会消灭在PCI配置内存中的另一个位置。但是不管这些PCIPCIPCI配置头都有一个和它在板上的槽位相关的偏移量。所以,举例来说,板上的第一个槽位的PCI0256〔全部的头都一样长度,256字节,依此类推。定义了系统相关的硬件机制使得PCI配置代码可以尝试检查一个给定的PCI总线上的全部可能的PCI配置头,试图读取头中的一个域〔通常是VendorIdentification域〕得到一些错误,从而知道那些设备存在而那些设备不存在。PCILocalBus标准描述了一种可能的错误信息:试图读取一个空的PCI槽位的VerdorIdentificationDeviceIndentification0xFFFFFFFF6.2256字节的PCI配置头的布局。它包括以下域:include/linux/pci.hVendorIdentification唯一的数字,描述这个PCI设备的制造者。Digital的PCIVendor Identification是0x1011而Intel是0x8086。DeviceIdentificationDigital21141快速以太网设备的设备标识0x0009。Status此域给除了设备的状态,它的位的含义由PCILocalBus标准规定。Command系统通过写这个域掌握这个设备。例如:允许设备访问PCII/O内存。ClassCode标识了设备的类型。对于每一种设备都有标准分类:显示、SCSISCSI的0x0100。BaseAddressRegisters这些存放器用于确定和安排设备可以使用的PCII/OPCI小和位置。InterruptPinPCI卡的物理管脚中的4个用于向PCI总线传递中断。标准中把它们标记为A、B、C和D。InterruptPin域描述了这个PCI设备使用那个管脚。通常对于一个设备来说这时硬件打算的。就是说每一次系统启动的时候,这个设备都使用同一个中断管脚。这些信息允许中断处理子系统治理这些设备的中断。 InterruptLinePCI配置头中的InterruptLine域用于在PCI初始化代码、设备驱动程序和Linux的中断处理子系统之间传递中断掌握。写在这里的数字对于设备驱动程序来讲是没有意义的但是它可以让中断处理程序正确地把一个中断从PCI设备发送到Linux操作系统中正确的设备驱动程序的中断处理代码处。Linux如何处理中断参看第7章。PCII/OandPCIMemoryAddress〔PCII/OPCI内存地址〕这两种地址空间用于设备和CPU上运行的Linux核心的它们的设备驱动程序通讯。例如:DECchip21141快速以太网设备把它的内部存放器映射到了PCII/OLinux设PCI内存空间来放置显示信息。直到PCIPCICommand域翻开了设备对于这些地PCI配置代码读写PCI配置地LinuxPCII/OPCI内存地址。PCI-ISABridges〔PCI-ISA桥〕这种桥把对于PCII/OPCI内存地址空间的访问转换成为ISAI/OISA内存访问,用来支ISAISAPCI容的需要会不断削减,将来会有只有PCIIntel8080PC时代,系统中ISAISA地址空间〔I/O和内存〕S5000AlphaAXP根底的计算机系统的ISA软驱驱动器的ISAI/O地址也会和第一台IBMPC一样。PCI标准保存了PCII/O和PCI内存的地址空间中的较低的区域保存给系统中的ISA外设并使用一PCI-ISAPCIISA访问。PCI-PCIBridges〔PCI-PCI桥〕PCI-PCI桥是特别的PCI设备把系统中的PCI总线粘和在一起简洁系统中只有一个PCI总线,当时单个PCI总线可以支持的PCI设备的数量有电气限制使用PCI-PCI桥增加更多的PCI总线允许系统支持更多的PCI设备。这对于高性能的效劳器尤其重要。固然, Linux完全支持使用PCI-PCI桥的使用。PCI-PCIBridges:PCII/OandPCIMemoryWindowsPCI-PCIPCII/OPCI6.1SCSIPCI-PCIPCI0传递到总1,其余的都被无视。这种过滤阻挡了不必要的地址信息遍历系统。为了到达这个目PCI-PCIPCII/OPCI内存地址空间访问的根底〔base〕和限制。一旦系统中的PCI-PCI桥设置好,只要Linux设备驱动程序只是通过这些窗口存取PCII/OPCI内存空间,PCI-PCI桥是不行见的。这是个重要的特性,使LinuxPCILinuxPCI-PCI桥在肯定程度上需要技巧才能配置,我们不久就会看到。PCI-PCIBridges:PCIConfigurationCyclesandPCIBusNumbering〔PCI-PCIPCI配cyclePCI总线编号〕CPUPCIPCI总线上的设备,必需有一种机制使得桥可以打算是否把配置cycle从它的主接口传递到次接口上。一个cycle就是它显示在PCI总线上的地PCIPCI016.36.4中显示。0PCIcyclePCIPCIPCI地址配置。配置cycle的位32:11看作是设备选择域。设计系统的一个方法是让每一个位选择一个不同的设备。这种状况下为11可能选择槽位0的PCI设备,位12选择槽位1的PCI设备,依此类推。另一种方法是把设备的槽位号直接写到位31:11中。一个系统使用哪一种机制依靠于系统的PCI内存掌握器。类型1的PCI配置cycle包括一个PCI总线号,这种配置循环被除了PCI-PCI桥之外的全部PCI设备无视。全部看到了类型1的PCI配置cycle的PCI-PCI桥都可以把这些信息向它们的下游传送。一个PCI-PCI桥是否无视PCI配置循环或者向它的下游传递,依靠于这个桥是如何配置的。每一个PCI-PCI桥都有一个主总线接口号和一个次总线接口号。主总线接口离CPU最近而次总线接口是离CPU最远的。每一个PCI-PCI桥都还有一个附属总线编号,这是在其次个总线接口之外可以桥接的最大的 PCI总线数目。或者说,附属总线编号是PCI-PCI桥下游的最大的PCI总线编号。当PCI-PCI桥看到一个类型1的PCI配置cycle的时候,它做以下事情:假设指定的总线编号不在桥的次总线编号和总线的附属编号之间就无视它。假设指定的总线编号和桥的次总线编号符合就把它转变成为类型0的配置命令假设指定的总线编号大于次要总线编号而小于或等于附属总线编号,就不转变地传递到次要总线接口上。6.931CPU1的11230的配置命令,3,使设备1响应它。每一个独立的操作系统负责在PCI配置阶段安排总线编号,但是不管使用哪一种编码方案,对于系统中全部的PCI-PCI桥,以下陈述都必需是正确的:全部位于一个PCI-PCI桥后面的PCI总线的编码都必需在次总线编号和附属总线编号之间〔包含PCI-PCI1PCI配置cycle统无法成功地找到并初始化系统中的PCILinux依据特定的挨次配置这些特别设备。参看6.6.2LinuxPCI桥和总线编码方案的描述以及一个可以工作的例子。LinuxPCIInitialization〔LinuxPCI初始化过程〕LinuxPCI初始化代码分为三个规律局部:PCIDeviceDriver0PCIPCI设备和桥。它建立一链接的数据构造的列表,描述系统的拓扑。另外,它还为系统中全部的桥编码。drivers/pci/pci.candinclude/linux/pci.hPCIBIOSPCIBIOSROMAlphaAXPBIOS效劳Linux核心也有供给了一样的功能的等价代码。参见arch/*/kernel/bios32.cPCIFixup系统相关的整理代码,整理和系统相关的在PCI初始化最终的内存疏松的状况。参arch/*/kernel/bios32.cLinuxKernelPCIDataStructures〔LinuxPCI数据构造〕LinuxPCIPCI6.5显示了数据构造之间的关系,它用来描述了图6.1中例如的PCI系统。每一个PCI设备〔包PCI-PCI桥pci_devPCIpci_bus的数据构造描述。结果是一个PCI总线的树型构造,每一个总线上有粘附着一些子PCI设备。由于一个PCI总线只能通过PCI-PCI桥到达〔除了主PCI总线,总线0,每一个pci_bus都包括一个它要通过PCI设备的指针〔PCI-PCI桥PCIPCI总线的父总线的一个子设备。6.5中没有显示的还有一个指向系统中全部的PCI设备的指针:pci_devices。系统中全部PCIpci_devLinux核心使用这个队列快速查找系统中PCI设备。ThePCIDeviceDriver〔PCI设备驱动程序〕PCI设备驱动程序完全不是一个真正的设备驱动程序,只是系统初始化的时候操作系统调用的个函数。PCI初始化代码必需扫描系统中全部的 PCI总线,查找系统中全部的PCI设备〔包括PCI-PCI桥接设备它使用PCIBIOS代码来查看它当前扫描的PCI总线上的每一个可能的槽位是否被占用。假设这个PCI槽位占用,它就建立一个描述这个设备的pci_dev数据构造,并把它链接到PCI设备的列表中〔由pci_deivices指向。drivers/pci/pci.cScan_busPCI初始化代码从PCI总线0开头扫描。它试图读出每一个可能的 PCI槽位中每一个可能的PCI设备的VendorIdentification和DeviceIdentification域当它找到了占用的槽位它就建立一个pci_dev数据构造来描述它。PCI初始化代码所建立的全部的pci_dev数据构造〔包括全部的PCI-PCI桥〕都链接到一个链接表:pci_devices。PCI-PCIpci_buspci_root指向的pci_buspci_devPCIPCIPCI-PCI桥,由于它的分类编码〔classcode〕0x060400LinuxPCI-PCI桥的PCI总线〔下游PCI-PCI桥,它们都一样被配置。这个过程成为深度〔depthwize〕算法:系统在宽度搜寻之前先在深度开放。看图6.1LinuxPCI总1SCSIPCI0上的显示设备。LinuxPCIPCI-PCI桥的次总线和附属总线编号。这些在下面的6.6.2节具体描述:ConfiguringPCI-PCIBridges–AssigningPCIBusNumbers〔配PCI-PCI-PCI总线编号PCII/O、PCIPCI配置地址空间的读写,PCI-PCI桥必需直到以下:PrimaryBusNumberPCI-PCI桥上游的总线SecondaryBusNumberPCI-PCISubordinateBusNumber从这个桥向下可以到达的全部总线中最高的总线编号。PCII/OandPCIMemoryWindows从这PCI-PCIPCII/OPCIbasesize。问题是当你期望配置任何指定的PCI-PCI是否下游还有其他PCI-PCI桥。就算知道,你也不知道它们将会被安排什么编号。答案是使用一个深度递归算法〔depthwiserecursivealgorithm。在每一个总线上找到任何PCI-PCI桥的时候都就给它们安排编号。对于找到的每一个PCI-PCI桥,就给它的次总线安排编号,并给它安排临时0xFF,并扫描它的下游全部的PCI-PCI桥并安排编号。这看起来相当简单,但是下面的实际例子能使这个过程更清楚。PCI-PCIBridgeNumbering:Step16.61〔Bridge1。1PCI1110xFF。这PCI11PCI1PCI110cycle,否则对于其他的总线编号就不变。这也LinuxPCI初始化代码需要做的,这样才能访问并扫描PCI1。PCI-PCIBridgeNumberingStep2Linux使用深度算法,所以初始化代码开头扫描PCI1。PCI-PCI22PCI-PCI桥,所以它的附属总线编号成为2,6.7PCI-PCI桥这时是如何编码的。PCI-PCIBridgeNumbering:Step3PCI初始化代码回来扫描PCI总线1,找到了另一PCI-PCI3130xFF。6.812或31PCIcycle现在PCI总线。PCIBIOSFunctions〔PCIBIOS函数〕PCIBIOS函数是通用的跨平台的一系列标准例程。例如,它们对于IntelAlphaAXP系统都是CPUPCI地址空间的访问。只有Linux核心和设备驱动程序需arch/*/kernel/bios32.cPCIFixupAlphaAXPPCIIntel〔根本不做任何事情〕Intel系BIOSPCILinux不需要做更多的事情,只是PCIIntel系统,需要做更多的配置:arch/kernel/bios32.cPCII/OPCI内存空间PCI-PCIPCII/OPCI内存地址窗口InterruptLine值,这些掌握设备的中断处理下面描述这些代码如何工作。FindingOutHowMuchPCII/OandPCIMemorySpaceaDeviceNeeds〔PCII/OPCI内存空间〕查询找到的每一个PCI设备,找出它需要多少PCII/O和内存地址空间。为此,把每一BaseAddressRegister1然后读出来。设备会在不关心的地址位返回1,有效地指定了〔BaseAddressRegisterPCII/OPCI内存空间必需在哪一个地址空间。这通过存放器的06.10显PCIPCII/O的根底地址存放器的两种形式。为了找出每一个给定的根底地址存放器需要多少地址空间,需要向全部的存放器写并读出来。设备会把不关心的地址位设为0,这样就有效地指明白需要的地址空间。这种设计示意了使用的全部2DECChip21142PCI快速以太PCII/OPCI0x100字节的地址。初始化代码为它21142的掌握和状态存放器就可以在这些地址见到。AllocatingPCII/OandPCIMemorytoPCI-PCIBridgesandDevices〔为PCI-PCIPCII/OPCI内存〕PCII/OPCI内存空间是有限的,其中有一些相当紧缺。对于非Intel系统PCI整理代码〔和IntelBIOS代码〕必需有效地为每一个设备安排它需要的内存量。安排PCII/OPCI内存的安排必需自然对齐。例如,假设一个设备恳求PCII/O地0xB0,那么安排的地址就必需是0xB0的倍数。另外,安排给任何桥的PCII/OPCI内存地址的根底必需分别对齐4K1M的边界。下游的设备给定的地址空间必需位于它全部的上游PCI-PCI桥的内存范围中间。所以有效地安排地址空间是有比较困难的问题。Linux使用的算法依靠于用PCI设备驱动程序建立的总线/设备树所描述的每一个设备,它依据PCII/O内存递增的挨次安排地址空间。又是使用递归算法,遍历 PCI初始化代码所建立的pci_bus和pci_dev数据构造。BIOS整理代码从PCI总线的根〔pci_root所指〕开头:分别把当前的全局PCII

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论