总线用来连接计算机和外部设备的,传输信号和数据,是数据通信的通道,由电气接口和编程接口组成,重点关注编程接口。
PCI是Peripheral Component Interconnect(外围设备互联)的简称,在pc系统广泛使用。
PCI三个显著优点:在计算机和外设间传递数据具有更好的性能;能够尽量独立于具体的平台;可以方便的实现即插即用。
体系结构,CPU和存储器之间是系统总线,系统总线扩展出PCI桥,桥生成出PCI总线,PCI上挂着PCI设备,只有PCI桥可以生成PCI总线。
通过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设备都有一组固定格式的寄存器,记录了设备里软硬件的一些特性,通过这些
寄存器驱动程序就可方便访问和控制外设。寄存器组织架构图
重要寄存器
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会自动传给程序。