# Linux Device Driver References - PCI Bus [TOC] ## Topology The BFD heiriarchy. Directory structure under sysfs repects the PCI topology. The [*GNU/Linux & PCI (Express)*](https://www.youtube.com/playlist?list=PLCGpd0Do5-I1hZpk8zi9Zh7SCnHrIQlgT) playlist contains a lot of intriguing example for interacting with PCI devices. ## Address spaces of a PCI device See Arch4001 lecture in the following references for detail. ### Configuration space This is somtimes called PCI header. Depending on the function of a PCI device (e.g. bridge or endpoint) the format may vary. See the `config` file under the sysfs directory of that PCI device. The contents of configuration space contains meta data of this PCI device. See [*GNU/Linux & PCI (Express) - Part 2: Print the PCI Header*](https://youtu.be/K10rOfEqgoE) and [*GNU/Linux & PCI (Express) - Part 3: Print the PCI(e) extended capabilities*](https://youtu.be/FfdYmmprVr8). The most important fields are probably the *Base Address Registers*, or the BARs. They point to the address where the other PCI address space of a PCI device is. See [*GNU/Linux & PCI (Express) - Part 4: Base Address Registers - Theorie*](https://youtu.be/OxGRIWStraE). ### MMIO space The MMIO space is used for interacting with the device. The layout of MMIO space is vendor-specific. It is up to the hardware vendor to decide whcih address does what. ## sysfs entries of PCI devices Details of each PCI device can be inspect under the files in the repective sysfs entry for the device. See [*5. Accessing PCI device resources through sysfs*](https://docs.kernel.org/PCI/sysfs-pci.html) in the kernel documentation. However those are raw bytes and are not the most human friendly. More often than not the `lspci` is used, instead of reading or writing those sysfs entries. ## `lspci` quick references In Linux the`lspci` and `setpci` are probably the most common tools to interact with the PCI devices. [*Debugging PCIe Issues using lspci and setpci*](https://support.xilinx.com/s/article/1148199) in refernce introducing those tools. ### List topology: -tv ``` $ lspci -tv ``` ### List everything: -vvv ``` $ lspci -vvv ``` ### List everything of a specific device: -vvvs ${BDF} ``` $ lspci -vvvs ${BDF} ``` ### List vendor ID and device ID: -nvmms ${BDF} ``` $ lspci -nvmms ${BDF} ``` ### Dump PCI configuration sapce of all devices: -xxx ``` $ lspci -xxx ``` ### Dump PCI configuration sapce of a specific device: -d ${BDF} -xxx ``` $ lspci -d ${BDF} -xxx ``` ## Further reading Also you may also want to know a little about the port I/O on x86_64. See the following videos from the same ourse 1. [*Arch4001 03 Input Output 02 Port IO 01 Intro*](https://youtu.be/TCS98oDHIjk) 2. [*Arch4001 03 InputOutput 02 PortIO 02 FixedIOPorts*](https://youtu.be/Y8Pv0jx6H20) 3. [*Arch4001 03 InputOutput 02 PortIO 03 VariableIOPorts*](https://youtu.be/TBEKybzvjkY) 4. [*Arch4001 03 Input Output 02 Port IO 04 Port Access Styles*](https://youtu.be/2KVB81cAWQ0) ## References For detailed knowledge about PCIe, see free [*Architecture 4001: x86-64 Intel Firmware Attack & Defense*](https://p.ost2.fyi/courses/course-v1:OpenSecurityTraining2+Arch4001_x86-64_RVF+2021_v1/course/) course by [Xeno Kovah](https://twitter.com/xenokovah?lang=en) of [Open Security Training 2](https://ost2.fyi). ### [Demystifying PCIe Perform ance and Tuning Parameters - Padmanabhan Rajanbabu](https://youtu.be/L2Phms469ns) {%youtube L2Phms469ns %} ### [[ENG] Sergei Miroshnichenko: Setting up the PCIe hotplug in Kernel for flexible setups / #LinuxPiter](https://youtu.be/gBX8aX8CQI4) {%youtube gBX8aX8CQI4 %} ### [Arch4001 04 PCIe 01 Intro 01 Legacy PCI Intro](https://youtu.be/TC9jkrU6UeM) {%youtube TC9jkrU6UeM %} ### [Arch4001 04 PCIe 01 Intro 02 Legacy PCI 3 Address Spaces](https://youtu.be/GZHGzXwVWrs) {%youtube GZHGzXwVWrs %} ### [Arch4001 04 PCIe 01 Intro 03 PCIe vs. PCI Differences](https://youtu.be/SQhYkJda5s0) {%youtube SQhYkJda5s0 %}