版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、浅谈Lin ux内核开发之PCI设备驱动Page 1 of 7Gen erated by Foxit PDF Creator ? Foxit Software For evaluati on only.http:/www.ibm.eom/developerworks/c n/linu x/l-cn-pci/i ndex.html2010-1-4浅谈Lin ux内核开发之PCI设备驱动Page 5 of 7Gen erated by Foxit PDF Creator ? Foxit Software For evaluati on only.浅谈Linux内核开发之PCI设备驱动级别:初级赵
2、昊翔(haoxiang), 软件工程师,Cisco Systems2009年6月11日本文介绍了 PCI的基本概念,并从Linux内核的角度出发,介绍了 PCI设备的初始化以及配置。PCI介绍随着计算机应用的不断更新和发展(比如百兆网卡、视屏流等),计算机内数据传输的带宽要求越来越高, 传统内部总线带宽已经远远不能满足这些应用的需要,因此人们推出了PCI总线标准PCI是Peripheral Compo nent In terco nn ect的缩写,它因为高性能、低成本以及良好的扩展性而在计算机系统中被广泛使用。上至服务器,下至嵌入式设备都能找到它的身影。图1显示了一个标准PCI总线的组织结构
3、图。图1.标准PCI总线的组织结构图从图中我们可以看出 PCI总线架构主要被分成三部分:1. PCI设备。符合PCI总线标准的设备就被称为 PCI设备,PCI总线架构中可以包含多个 PCI设备。图 中的Audio、LAN都是一个PCI设备。PCI设备同时也分为主设备和目标设备两种,主设备是一次访问 操作的发起者,而目标设备则是被访问者。2. PCI总线。PCI总线在系统中可以有多条,类似于树状结构进行扩展,每条PCI总线都可以连接多个PCI设备/桥。上图中有两条 PCI总线。3. PCI桥。当一条PCI总线的承载量不够时,可以用新的PCI总线进行扩展,而 PCI桥则是连接PCI总线之间的纽带。
4、图中的 PCI桥有两个,一个桥用来连接处理器、内存以及PCI总线,而另外一条则用来连接另一条PCI总线。PCI总线操作PCI总线操作表示主设备向目标设备所发起的操作请求,最多有16种类型。主要类型有:IO方式读/写,Memory方式读/写, Configuration 方式读/写等。PCI配制空间对于软件开发者来说,该如何对PCI设备进行编程呢? PCI总线标准中定义了一套配置空间寄存器用于读取或者设置PCI设备的信息。每个 PCI设备/桥都有自己的配置空间寄存器。配置空间共有256字节,设备类型不同,其配置空间的布局也不尽相同。设备类型的区分可以通过配置空间内 的Header Type寄存器
5、(OEh)进行,该寄存器值为 00h表示当前设备是一个 PCI设备,01h表示当前设备 是一个PCI桥。配置空间的前64字节是配置空间起始段,它对于每种类型的设备都是相同的。显示了PCI设备的配置空间起始段。图2. PCI设备的配置空间起始段r 31lfi1501Dexict IDYwidor IDOOhStatusCommand04hClai? Cod;Rfv sion IDOS!13:S7三幵定:甘Tim?:OChAddress Register 1lOhBa?* Addr 已耳壮卫即已214hAddress 栗fgwer 3l$h3as? Addrtss Renier 4ICh3asf
6、Address?2Ch24hCsidtu? CIS PointyJ$hSubsvtrem IDSubsyieir*ndoi ID2ChExpansion R0: Base Addrtss匚 apabitj pQin:er34h畑 口I2込.GritIntirrupr PinInrerrupT Line3Ch图3显示了 PCI桥的配置空间起始段图3. PCI桥的配置空间起始段r 3i16150IDA'endor IDOOh04hSiacuCommail JCodeReiisioa IDro$hBISTHeader TypeL arene v Timer口血:皱SizeroctiBat?
7、Addr?tt R亡工即烈 1LOhr uhLatency TimerSuborduiare 虹 XtunberSecQndaryF Bui NumberP-unary Bi肝 Xumlwrl£h iChI O Lun:10 Bas-f20112-lh2ShPE良:边他栄 >Ie;uon-?refccajt;e 匚询0疔 3a=e匕出换讨新b叢315? Upper 32 3i:sLimi: Vppr 32 別的r:chI O Limit Upper 16 BibIO E於亡 Upper 1(5 Bits30h34hRe 汎 wdCapabiliiie? PokierHxpano
8、n ROM Base Addres?3$hBridce ControlInternipt PinInter nipt Lin?pCh配置空间寄存器有些是只读的,有些是可写的,下面介绍几个在编程时会用到的寄存器Device ID 和 Ven dor ID 寄存器这两个寄存器分别存放了设备信息和厂商信息(值在 0x0000和OxFFFF之间,但不能取OxFFFF ),因此软 件开发者可以通过读取这两个寄存器的值,并与0xFFFF比较,从而判断当前设备是否有效。Comma nd 和 Status 寄存器Comma nd寄存器存放了设备的配置信息,比如是否允许 Memory/IO方式的总线操作、是否为
9、主设备等。 Status寄存器存放了设备的状态信息,比如中断状态、错误状态等。Header Type 寄存器这个寄存器前面曾经提过,它定义了设备类型,比如 PCI设备、PCI桥等。Base Address 寄存器这个寄存器有三个作用。1该寄存器存放了 Memory/IO访问空间的起始地址。2该寄存器存放了 Memory/IO访问空间的大小,这个数据可以通过下面的方式读出:a. 往寄存器里写 OxFFFFFFFF ;b. 读出寄存器的值,并取反;c. 将上一步的值加上1后就是该空间的大小。3. 该寄存器定义了这段地址空间的访问类型(Memory方式还是IO方式)。PCI设备最多有6个Base A
10、ddress 寄存器,而 PCI桥最多有2个Base Address 寄存器。Subord in ate Bus Number,Sec ondary Bus Number 禾口 Primary Bus Number 寄存器这三个寄存器只在 PCI桥配置空间中存在,因为 PCI桥会连接两条PCI总线,上行的总线被称为 Primary Bus,下行的总线被称为 Secondary Bus , Primary Bus Number 和 Secondary Bus Number 寄存器分别存储 了上行和下行总线的编号,而Subordi nate Bus Number 寄存器则是存储了当前桥所能直接或者
11、间接访问到的总线的最大编号。PPC对于PCI的支持通常PPC会提供一个(或更多的) PCI控制器来连接PCI总线,通过PCI控制器,CPU可以发起 Con figuration读写操作来访问所连接的所有PCI设备/桥的配置空间。每个 PCI设备/桥都会用(总线号,设备号,功能号)这一组合来进行编号,因此在PCI控制器中输入设备对应的(总线号,设备号,功能号)就能寻址到具体的PCI设备/桥。以PPC8548为例,它提供了两个寄存器来实现Configuration操作,分别是CFG_ADDR和CFG_DATA寄存器,如果想对某个设备发起读/写操作,则首先将该设备的(总线号,设备号,功能号)写入 C
12、FG_ADDR中,这代表寻址一个具体的PCI设备,同时在CFG_ADDR中写入需要操作的配置空间寄存器的编号,最后从CFG_DATA中读取/写入相应的数据即可。Linux内核对PCI的支持Linux内核(2.6版本)在初始化之初就对所有PCI设备进行了扫描并且配制,具体操作分为下面几个步骤。编译时的PCI配制如果想要Linux内核支持PCI,首先需要对其配制文件进行相应的修改,在config文件中需要配置下面的宏参数。1. Linux提供了 PCI配制全局控制宏参数 CONFIG_PCI,它控制着PCI控制器和设备是否能够被配制的流程,因此该宏值需要被设置成“ Y一2. 对于某些处理器来说,比
13、如PPC85XX、PPC83XX等,它们提供了两个或者更多的PCI控制器,因此在 config 文件中专门提供了诸如 CONFIG_MPC85xx_PCI2 、CONFIG_MPC83xx_PCI2 等宏参数,它 们控制着第二个(或更多的)PCI控制器的配置流程,因此如果需要使用第二个(或更多的)PCI控制器时,需要将相应的宏值设置成“ Y'在编译内核之前,如果在 config文件中提供了以上宏参数的设置,则编译出来的内核映像提供了对于PCI支持的功能。PCI相关数据结构Linux提供了三类数据结构用以描述PCI控制器、PCI设备以及PCI总线。PCI控制器PCI控制器用pci_con
14、troller结构来描述,它有以下几个主要的属性:? index :该属性标志PCI控制器的编号。? next :该属性指向下一个 PCI控制器,通过next属性,PCI控制器可以形成一个单向链表。? first_busno :该属性标志了连接在该控制器上第一条总线的编号。? last_busno :该属性标志了连接在该控制器上最后一条总线的编号。? ops :该属性标志了当前 PCI控制器所对应的PCI配制空间读写操作函数。? io_space :该属性标志了当前 PCI控制器所支持的10地址空间。? mem_space :该属性标志了当前 PCI控制器所支持的Memory地址区间。? cf
15、g_addr :该属性标志了当前 PCI控制器发起Configuration访问方式时所需要写入的地址空间。? cfg_data :该属性标志了当前 PCI控制器发起Configuration访问方式时所需要读写的数据空间。? bus :该属性标志了当前 PCI控制器所连接的PCI总线,它对应的数据结构是pci_bus。PCI总线PCI总线用pci_bus结构来描述,它有以下几个主要的属性:? pare nt :可通过该属性索引到上层PCI总线。? self :该属性标志了连接的上行PCI桥(对应的数据结构是pci_dev )。? children :该属性标志了总线连接的所有PCI子总线链表
16、。? devices :该属性标志了总线连接的所有PCI设备链表。? ops :该属性标志了总线上所有PCI设备的配制空间读写操作函数。? number :该属性标志了当前 PCI总线的编号。? primary :该属性标志了 PCI上行总线编号。? secondary :该属性标志了 PCI下行总线编号。? subordinate :该属性标志了能够访问到的最大总线编号。? resource :该属性标志了 Memory/IO 地址空间。PCI设备PCI设备用pci_dev结构来描述,它有以下几个主要的属性:? global_list : Linux定义了一个全局列表来索引所有的PCI设备,
17、该属性标志了这个全局列表的首指针。? bus :该属性标志了当前设备所在的PCI总线(对应的数据结构是pci_bus )。? devfn :该属性标志了设备编号和功能编号。? ven dor :该属性标志了供应商编号。? device :该属性标志了设备编号。? driver :该属性标志了设备对应的驱动代码(对应的数据结构是pci_driver )。? irq :该属性标志了中断号。? resource :该属性标志了 Memory/IO 地址区间。内核里的PCI数据结构图当Linux内核在做PCI初始化工作时,它会根据图4建立一个由pci_controller、pci_bus和pci_de
18、v三者组成的一个组织结构图。根据这个结构,软件开发者可以很方便的通过_PCI控制器索引到9每个 PCT设备或者PCI总线。http:/www.ibm.eom/developerworks/c n/linu x/l-cn-pci/i ndex.html2010-1-4浅谈Lin ux内核开发之PCI设备驱动Page 6 of 7Gen erated by Foxit PDF Creator ? Foxit Software For evaluati on only.http:/www.ibm.eom/developerworks/c n/linu x/l-cn-pci/i ndex.html20
19、10-1-4浅谈Lin ux内核开发之PCI设备驱动Page 9 of 7Gen erated by Foxit PDF Creator ? Foxit Software For evaluati on only.图4.组织结构图p ci_c ontrollff卩 c uparent cyiiliire 口self dwices bus-unesinext>busbu弓sib'ingsiblingp&.devpci_d 的pcLdevPCI控制器初始化parttit c:iLd:en next self decs bus=Opci_de-vpci_de-| nextnex
20、tsiblingsibling当一个支持PCI的内核映像开始运行时,它会在系统初始化时对PPC85XX 为例)。PCI进行配置。函数调用链如下所示(以图5.函数调用链内核从start_kernel()函数处开始进行系统初始化,一直执行到mpc85xx_setup_hose()函数处便是配制 PCI控制器以及连接在该控制器上所有设备的过程。一 一所有这些函数的定义处都加上了 _init的符号类型,由 _init修饰的函数表明在链接最终的内核映像时,这些 函数将被放在一个特殊的初始化代码段中(.init.text,可以在链接文件 vmlinux.lds.S中找到相关的段描述), 这个初始化代码段会
21、随着内核初始化完成而被释放。在这一步骤中,内核会对它所支持的所有PCI控制器进行初始化工作,每个PCI控制器都对应一个pci_controller属性的变量,初始化工作会在这些变量中设置Memory/IO访问空间的起始地址以及结束地址、设置当前PCI控制器所连接的第一条和最后一条PCI总线编号等等。PCI自动扫描系统如何知道当前连接了多少PCI设备?有多少根PCI总线?每个PCI设备的访问空间如何配置?等等。这些都得靠PCI自动扫描来完成。PCI自动扫描主要做下面的工作:1. 扫描PCI总线,识别PCI总线上的所有设备。2. 对于连接在PCI总线上的所有PCI桥进行总线编号。3. 对于连接在P
22、CI总线上的所有PCI设备和PCI桥进行Memory/IO 访问空间的配置。这部分代码在 pciauto_bus_scan() 函数中(位于 arch/ppc/syslib/pci_auto.c 中)。识别PCI总线上的设备PCI总线扫描的原理是从总线 0扫描到总线255,对于每条总线,系统都会扫描所有(总线号,设备号,功 能号),通过 Con figuration方式读出每个设备的 Device ID和Vendor ID寄存器,如果这两个寄存器的值是 个有效值(非OxFFFF ),则说明当前设备是个有效的PCI设备/桥。进而再读取该设备的 Header Type寄存器,如果该寄存器为1,则表
23、示当前设备是 PCI桥,否则是PCI设备。对所有PCI总线进行编号PCI桥如何知道它所连接的 PCI总线情况呢?这就需要对PCI桥进行总线编号。前面介绍过PCI桥提供了Primary Bus Number 、Sec on dary Bus Number 和 Subordi nate Bus Number 三个寄存器用于标志该桥所连接 的PCI总线,下面通过一个示例来说明内核对于PCI总线是如何进行编号的。图6.示例1. 系统运行初始,Bus A为0,通过上面的PCI总线扫描得到连接在 Bus A上的PCI桥(即图中的Bridge 1 )。2. 下面开始设置Bridge 1的Bus寄存器。将Pr
24、imary Bus Number 寄存器设置成Bus A的编号,即0。将Secondary Bus Number 寄存器设置成 Bus B的编号,它的值等于(Bus A + 1 ),也就是1。由于 暂时无法知道该桥所能访问的所有下行总线数目,Subordinate Bus Number 寄存器暂时设置成 OxFF。3. 当扫描完所有Bus A上所有(设备号,功能号)后,开始扫描Bus B,Bus B的编号在扫描完Bus A后已经得到,为1。Bus B的扫描方法同步骤(1),先扫描出Bus B上的PCI桥(即图中的Bridge 2),然后配置 Primary Bus Number 寄存器为 1,
25、 Secondary Bus Number 寄存器为 2,而 Subordinate Bus Number 寄存器依然为 OxFF。4. Bus B扫描完后得到Bus C的编号,为2。下面开始扫描 Bus C,因为Bus C上没有PCI桥,于是在 扫描完其它(设备号,功能号)后, Bus C的扫描结束。5. 由于Bridge 2所能访问到的最大 Bus编号是2,因此重新设置 Bridge 2的Subordinate Bus Number 寄存器为2。6. 由于Bridge 1所能访问到的最大 Bus编号也是2,因此重新设置 Bridge 1的Subordinate Bus Number 寄存器
26、为2。7. 总线编号结束。配置访问空间当系统需要访问 PCI设备时,它需要产生 Configuration、Memory或者IO的读写操作,对于 Memory/IO 的 访问方式来说,它们需要定义一个地址范围,落在这个地址范围的操作会被认为是相应的Memory/IO的读写操作。通常PCI设备提供了最多6组Base Address寄存器,在PCI总线扫描时,每当扫描出一个可用的PCI设备后,会对该设备的 Base Address寄存器进行Memory/IO访问空间的配置。而对于PCI桥来说,它只提供了 2组Base Address寄存器,当PCI总线扫描出一个 PCI桥后,也会对该桥 的Base
27、 Address寄存器进行Memory/IO访问空间的配置。需要注意的是,在构建系统之初,需要明确当前系统的地址范围,戈y分出特定的物理地址作为PCI Memory或者PCI IO空间,在给PCI设备/桥进行访问空间配置时,就是取事先约定的地址空间中的某段地址进行配 置,所有设备/桥的访问地址不能冲突。定义系统的Memory/IO 访问空间是在 mpc85xx_setup_hose() 函数中提供的(位于 arch/ppc/syslib/ppc85xx_setup.c 中)。PCI设备和总线初始化这一操作在pcibiosnit()函数中进行(位于 arch/ppc/kernel/pci.c 中)。它会在前面操作结束后,对PCI总线和PCI设备分别分配pci_bus和pci_dev类型的节点,并建立如所示的组织结构关系。Lin ux的PCI设备初始化Linux会将PCI的相关
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025振动沉管灌注桩整体机械出租合同
- 2025不动产权籍调查技术咨询服务合同
- 课题申报参考:凌家滩史前玉器艺术价值挖掘与传承创新路径研究
- 学科交叉融合与创新能力提升
- 会展合同管理与风险防范考核试卷
- 二零二五年度森林碳汇树木种植项目合同4篇
- 2025年沪教版选择性必修1历史下册阶段测试试卷
- 2025年新世纪版九年级地理上册阶段测试试卷
- 2025年冀教版九年级地理上册月考试卷
- 2025年华师大版选择性必修1化学下册月考试卷
- 2024-2025学年北京石景山区九年级初三(上)期末语文试卷(含答案)
- 第一章 整式的乘除 单元测试(含答案) 2024-2025学年北师大版数学七年级下册
- 春节联欢晚会节目单课件模板
- 中国高血压防治指南(2024年修订版)
- 糖尿病眼病患者血糖管理
- 抖音音乐推广代运营合同样本
- 教育促进会会长总结发言稿
- 北师大版(2024新版)七年级上册数学第四章《基本平面图形》测试卷(含答案解析)
- 心理调适教案调整心态积极应对挑战
- 喷漆外包服务合同范本
- JT-T-390-1999突起路标行业标准
评论
0/150
提交评论