总线用来连接计算机和外部设备的,传输信号和数据,是数据通信的通道,由电气接口和编程接口组成,重点关注编程接口。

PCI是Peripheral Component Interconnect(外围设备互联)的简称,在pc系统广泛使用。

PCI三个显著优点:在计算机和外设间传递数据具有更好的性能;能够尽量独立于具体的平台;可以方便的实现即插即用。

通过PCIe总线控制GPU_PCI总线


体系结构,CPU和存储器之间是系统总线,系统总线扩展出PCI桥,桥生成出PCI总线,PCI上挂着PCI设备,只有PCI桥可以生成PCI总线。


通过PCIe总线控制GPU_通过PCIe总线控制GPU_02



通过PCI桥生成PCI总线0,0号上有PCI显卡,在这条PCI总线上还可再接PCI桥,PCI-PCI桥,PCI-ISA总线,‘-’左边是源头总线,‘-’右边是目的总线。

PCI设备的定位寻址:在系统中有很多PCI设备,有三个参数参数确定PCI位置,每个设备由一个总线号,一个设备号和一个功能号确定(类似地球经纬度)。PCI规范规定一个系统最多有256条PCI总线,每条PCI总线最多接32个设备,每个设备最多有8个功能。/proc/iomem描述所有的设备I/O在内存地址空间上的映射,地址从1G开始的第一个设备在/proc/iomem中是如何描述的:

40000000 — 400003ff :0000 :00:1f.1  

这是一个PCI设备: 后面三个段分别对应总线号、设备号和功能号,0000 :00:1f.1是这个PCI外设的地址,它以冒号和逗号分为4个部分,第一个16位表示域,第二个8个八位表示总线号,第三个5位表示设备号,最后三位表示功能号,总线号是00,设备号是1f,功能号为1。使用lspci命令可以查看系统中PCI设备。

PCI配置寄存器

每个PCI设备都有一组固定格式的寄存器,记录了设备里软硬件的一些特性,通过这些

寄存器驱动程序就可方便访问和控制外设。寄存器组织架构图


通过PCIe总线控制GPU_PCI总线_03



重要寄存器

00H---01H Vender ID  制造商标识  02H---03H  Device ID 设备标识

//判断是否是驱动该去操作的设备

04H---05H Command  命令寄存器           06H---07H Status    状态寄存器

10H---13H Base Address Register0  基地址寄存器0

14H---17H Base Address Register1  基地址寄存器1

18H---1bH Base Address Register2  基地址寄存器2

1cH---19H Base Address Register3  基地址寄存器3

20H---23H Base Address Register4  基地址寄存器4

24H---27H Base Address Register5  基地址寄存器5

//记录芯片在系统中的物理基地址

3cH  Interrupt Line 中断线寄存器     //记录中断号

3dH  Interrupt Pin  中断引脚寄存器 //为0,不支持中断,非0,支持中断

在Linux内核中,PCI驱动使用struct pci_driver结构来描述:

struct pci_driver {

。。。。。。。。。。。。。

const pci_device_id  *id_table ;  //这个PCI程序支持的所有设备

int (*probe) (struct pci_dev *dev,  const pci_device_id  *id) ;

//当注册PCI驱动程序时,程序会在系统寻找它支持的设备,将系统中PCI设备拿来和id_table对比,调用probe函数驱动找到的设备。

void (*remove) (struct  pci_dev  *dev) ;

//拔掉PCI设备时调用

。。。。。。。。。。。。。

}

pci_register_driver (struct pci_driver  *drv)  注册PCI驱动

在PCI驱动使用PCI设备的任何资源(I/O区或中断)之前,驱动必须调用如下函数来使能设备:

int pci_enable_device (struct pci_dev  *dev)

pci_resource_start (struct pci_dev *dev, int bar )  访问PCI配置寄存器里的基地址寄存器,返回指定区域的起始地址,这个区域通过参数bar指定,范围从0-5,表示6个寄存器中的一个。中断号存放于寄存器PCI_INTERRUPT_LINE中,Linux会自动传给程序。