In this article we will explain the basics of PCI, PCIe and the lspci command to display information on your system.
What is PCI?
PCI, or Peripheral Component Interconnect is an interface to add additional hardware components to a computer system. PCIe or PCI Express is the updated standard that is used today. For example let's say you want to add a Ethernet card to your computer so that it can access the internet and exchange data. Well the card needs a protocol to communicate with the rest of the internal system, PCI can be the standard interface used to add this card to your system. You still need a driver for this card in order for the kernel to use it, however PCI is the slot, and bus and interface that will be used to add the hardware into the system with a standard interface. Creation of a PCI linux driver will follow some standard interfaces you can see documentation for creating a PCI linux driver here. You can see from the struct below the standard methods that must be implemented. Methods such as probe, remove, suspend, resume, etc.struct pci_driver
struct list_head node;
const char *name;
const struct pci_device_id *id_table;
int (*probe)(struct pci_dev *dev, const struct pci_device_id *id);
void (*remove)(struct pci_dev *dev);
int (*suspend)(struct pci_dev *dev, pm_message_t state);
int (*resume)(struct pci_dev *dev);
void (*shutdown)(struct pci_dev *dev);
int (*sriov_configure)(struct pci_dev *dev, int num_vfs);
const struct pci_error_handlers *err_handler;
const struct attribute_group **groups;
struct device_driver driver;
struct pci_dynids dynids;
PCI Speeds and Uses
PCI 3.0 can run data up to 1GB/Sec per lane. Different devices can have more than one lane, so it's possible that individual devices can have multi-gigabytes of data transfer rate. These numbers are always improving as new versions of the specification come out and new hardware comes out, so always check for the latest and fastest you can find. Types of components and gadgets that you can buy that plug into a PCI interface include: WIFI adapters, Bluetooth, NVME Solid State Storage cards, Graphics cards and more.
Exploring the lspci Command
I have created a Ubuntu 19.04 instance on Google cloud and will now run the lspci command and see what happens.
What you see is one line per device with a numerical code and a verbal description of the device. There are actually 5 fields displayed in this output per line: Slot, Class, Vendor, Device, and Revision.
So breaking down the first line what we have:
Class: Host bridge
Vendor: Intel Corporation
Device: 440FX - 82441FX PMC
And looking at Slot 00:04.0 that is our Ethernet controller, which appears to be a virtual device as part of the virtual magic of Google's cloud deployment.
To get more detailed, verbose information about each PCI slot, run the following command:# lspci -vmm
This command will break down each line into its component fields and allow you to analyze each device with more descriptive labels.
You can also try the -v option for more verbose output# lspci -v
And use double v or tripple v for verby verbose output:# lspci -vvv
Or try the -mm option for script readable output format.# lspci -mm
In order to see which kernel driver is being used for each device run -k option.
Many of my devices are using virtio-pci driver.
Lastly you can even see a hexadecimal dump of “the standard part of the configuration space” for each PCI device. You should be a real kernel hacker to figure out how to use that information. -x option is what gives you the dump output.# lspci -x
The lspci command is a standard Linux command that can be used to list information about the PCI connected devices on your system. This can be useful to know what hardware peripherals you have. Its also super useful for developers, device driver creators, low level system folks to query information about the devices, the drivers and the system. Enjoy using lspci.