PCI Drivers [LDD3 12]

因为很多device都是PCI device,所以本章重点看一下PCI(Peripheral Component Interconnect),首先明确一点,PCI是总线类型,总线有两种接口类型组成,electrical interface和programming interface,软件层面都属于programming interface。

12.1. The PCI Interface


PCI由一系列的spec组成,我们只关注kernel里面,PCI device driver如何找到PCI device并且访问它。

PCI总线是为了替代ISA总线,主要为了实现三个目标:

1,提高计算机和外设之间数据传输的速率

2, 让外设与平台无关

3, 方便的添加和移除PCI设备

第一个目标,PCI总线提供了更好的频率,比如25MHz或者33MHz,66Mhz,甚至133MHz。PCI可以可以实现32bit或者64bit总线位宽,并且同时设计为与平台无关,比如IA-32,Alpha,PowerPC,SPARC64,以及IA-64系统。对于developer而言,PCI支持动态检测PCI设备,PCI设备在系统bootup阶段就会被配置,driver后续能直接访问device的配置信息,从而方便的完成设备初始化。

12.1.1. PCI Addressing

PC上存在很多的PCI设备,如何快速的找到某一个特定的PCI device?这就涉及到PCI设备的寻址。

每一个PCI device在系统中都有一个唯一的ID,这个ID由bus number,device number,function number组成,这三个值的组合在系统中是唯一的,所以说只要知道了BDF(Bus,Device,Function)值,就能找到对应的PCI device。

PC的标准,最开始只支持256个bus number,但是对于大型系统而言,256个bus显然太少了。所以Linux增加了一个domain的概念,一个domain最多包含256个bus,一个bus最多包含32个device,一个device最多包含8个function,BDF加起来就是16bit,所以一个16bit的地址就能标记一个function。不过device driver不需要直接使用BDF,而应该通过pci_dev来访问PCI device。

如果一个系统中有不止一个bus,就需要通过bus bridge把这些bus聚合到一起。而绝大部分的PCI都有不止一个PCI bus,所以一般都有PCI bus bridge,由PCI bridge把这些PCI bus链接到系统总线。PCI的整个系统按照树形结构来管理,每一个bus链接到上层的bus,直到bus 0,也就是root bus为止:

通常情况下,不需要使用BDF来访问PCI 设备,因为都被隐藏在了struct pci_dev这个结构体里面,但是有些情况下,需要直接使用BDF,比如在用户态,通过lspci查看pci device的id等情况,这个时候就需要打印所有PCI设备的BDF。比如某个PCI device的BDF是0000:00:00.1,其中前面的0000是domain,后面的00是8bit bus number,最大为255,再后面的00是5bit device number,最大为31,最后的1是3bit的function,最大为7.

$ lspci | cut -d: -f1-3
0000:00:00.0 Host bridge
0000:00:00.1 RAM memory
0000:00:00.2 RAM memory
0000:00:02.0 USB Controller
0000:00:04.0 Multimedia audio controller
0000:00:06.0 Bridge
0000:00:07.0 ISA bridge
0000:00:09.0 USB Controller
0000:00:09.1 USB Controller
0000:00:09.2 USB Controller
0000:00:0c.0 CardBus bridge
0000:00:0f.0 IDE interface
0000:00:10.0 Ethernet controller
0000:00:12.0 Network controller
0000:00:13.0 FireWire (IEEE 1394)
0000:00:14.0 VGA compatible controller
$ cat /proc/bus/pci/devices | cut -f1
0000
0001
0002
0010
0020
0030
0038
0048
0049
004a
0060
0078
0080
0090
0098
00a0
$ tree /sys/bus/pci/devices/
/sys/bus/pci/devices/
|-- 0000:00:00.0 -> ../../../devices/pci0000:00/0000:00:00.0
|-- 0000:00:00.1 -> ../../../devices/pci0000:00/0000:00:00.1
|-- 0000:00:00.2 -> ../../../devices/pci0000:00/0000:00:00.2
|-- 0000:00:02.0 -> ../../../devices/pci0000:00/0000:00:02.0
|-- 0000:00:04.0 -> ../../../devices/pci0000:00/0000:00:04.0
|-- 0000:00:06.0 -> ../../../devices/pci0000:00/0000:00:06.0
|-- 0000:00:07.0 -> ../../../devices/pci0000:00/0000:00:07.0
|-- 0000:00:09.0 -> ../../../devices/pci0000:00/0000:00:09.0
|-- 0000:00:09.1 -> ../../../devices/pci0000:00/0000:00:09.1
|-- 0000:00:09.2 -> ../../../devices/pci0000:00/0000:00:09.2
|-- 0000:00:0c.0 -> ../../../devices/pci0000:00/0000:00:0c.0
|-- 0000:00:0f.0 -> ../../../devices/pci0000:00/0000:00:0f.0
|-- 0000:00:10.0 -> ../../../devices/pci0000:00/0000:00:10.0
|-- 0000:00:12.0 -> ../../../devices/pci0000:00/0000:00:12.0
|-- 0000:00:13.0 -> ../../../devices/pci0000:00/0000:00:13.0
`-- 0000:00:14.0 -> ../../../devices/pci0000:00/0000:00:14.0

PCI hardware会提供三种地址空间的查询:memory locations, I/O ports,

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值