# 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 %}