我们在 浅谈Linux PCI设备驱动(一)中(以下简称 浅谈(一) )介绍了PCI的配置寄存器组,而Linux PCI初始化就是使用了这些寄存器来进行的。后面我们会举个例子来说明Linux PCI设备驱动的主要工作内容(不是全部内容),这里只做文字性的介绍而不会涉及具体代码的分析,因为要分析代码的话,基本就是对 Linux内核源代码情景分析(下册)第八章的解读,读者若想分析代码,可以参考该书的内容,我们这里就不去深入分析这些代码了。
Linux PCI设备驱动代码必须扫描系统中所有的PCI总线,寻找系统中所有的PCI设备(包括PCI-PCI桥设备)。系统中的每条PCI总线都有个编号number,根PCI总线的编号为0。系统当前存在的所有根总线(因为可能存在不止一个Host/PCI桥,那么就可能存在多条根总线) 都通过其pci_bus结构体中的node成员链接成一个全局的根总线链表,其表头由struct list_head类型的全局变量pci_root_buses来描述,我们在/linux-2.4.18/linux/drivers/pci/pci.c的38行可以看到如下定义:
LIST_HEAD(pci_root_buses);
而根总线下面的所有下级总线则都通过其pci_bus结构体中的node成员链接到其父总线的children链表中。这样,通过这两种PCI总线链表,Linux内核就将所有的pci_bus结构体以一种倒置树的方式组织起来。
另外,每个PCI设备都由一个pci_dev结构体表示,每个pci_dev结构体都同时连入两个队列,一方面通过其成员global_list挂入一个总的pci_dev结构队列(队列头是pci_devices);同时又通过成员bus_list挂入其所在总线的pci_dev结构队列devices(队列头是pci_bus.devices,即该pci设备所在的pci总线的devices队列),并且使指针bus(指pci_dev结构体里的bus成员)指向代表着其所在总线的pci_bus结构。如果具体的设备是PCI-PCI桥,则还要使其指针subordinate指向代表着另一条PCI总线的pci_bus结构。同样我们在/linux-2.4.18/linux/drivers/pci/pci.c的39行可以看到如下定义:
LIST_HEAD(pci_devices);
对于PCI设备链表,我们可以通过图1来理解。
注:该图摘自Linux设备驱动开发详解 第