Over 10 years we helping companies reach their financial and branding goals. Onum is a values-driven SEO agency dedicated.


What is the Base Address Register (BAR) in PCIe?

Imagine a world where communication between devices is like a complex dance, every move planned and coordinated. In this scenario, the Base Address Register (BAR) on PCIe plays a key role. If you’ve ever wondered what it means or how it affects your devices, you’re in the right place. In this exploration, we will unravel the enigma behind the Base Address Register (BAR).

What is the Base Address Register (BAR) in PCIe?

The Base Address Register, or simply BAR, is a crucial concept in the world of PCIe (Peripheral Component Interconnect Express). When your electronic devices need to communicate, the BAR acts as a “map” indicating the exact location of the information they need to exchange.

Detailed breakdown of the BAR:

Understanding the BAR: The BAR contains vital information about the memory addresses and input/output (I/O) ports that devices use to communicate. Essentially, it is the key that allows electronic components to speak the same language.

How the BAR Works: When a PCIe device connects to the motherboard, it uses its BAR to tell the operating system which memory areas and I/O ports it needs. This process facilitates seamless communication between the different components of your system.

Why does the Base Address Register (BAR) Matter?

Imagine your computer as an interconnected city, each device is a building and the BAR is the master blueprint. Without the BAR, devices would not be able to find their addresses and would be lost in the digital chaos.

Optimising Performance with the Base Address Register (BAR):

When it comes to maximising the performance of your system, understanding and optimising the BAR is key. Through intelligent configurations, you can improve the efficiency of communication between your devices, enabling faster and smoother data flow.

The Base Address Register (BAR) on PCIe is like the GPS of your electronic devices. It enables orderly and efficient communication, ensuring that each component knows exactly where to find the information it needs.

We hope this exploration of the Base Address Register has cleared up your doubts and given you a deeper understanding of the vital infrastructure that keeps your electronic devices connected.

Remember, in the complex dance of technology, the BAR is the conductor of the orchestra, guiding each device to play the tune of efficiency. Keep exploring the fascinating world of PCIe and keep your system in tune!


Linux kernel point of view

A good way to learn something is to interact with it, so let’s use the Linux kernel for that.

Here is a minimal PCI example on a QEMU emulated device: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/366b1c1af269f56d6a7e6464f2862ba2bc368062/kernel_module/pci.c

The first 64 bytes of the PCI configuration are standardized as:

Image from LDD3.

So we can see that there are 6 BARs. The wiki page then shows the contents of each BAR:

The region width requires a magic write however: How is a PCI / PCIe BAR size determined?

This memory is setup by the PCI device, and gives information to the kernel.

Each BAR corresponds to an address range that serves as a separate communication channel to the PCI device.

The length of each region is defined by the hardware, and communicated to software via the configuration registers.

Each region also has further hardware defined properties besides length, notably the memory type:

  • IORESOURCE_IO: must be accessed with inX and outX
  • IORESOURCE_MEM: must be accessed with ioreadX and iowriteX

Several Linux kernel PCI functions take the BAR as a parameter to identify which communication channel is to be used, e.g.:

mmio = pci_iomap(pdev, BAR, pci_resource_len(pdev, BAR));
pci_resource_flags(dev, BAR);
pci_resource_start(pdev, BAR);
pci_resource_end(pdev, BAR);

By looking into the QEMU device source code, we see that QEMU devices register those regions with:

memory_region_init_io(&edu->mmio, OBJECT(edu), &edu_mmio_ops, edu,
                "edu-mmio", 1 << 20);
pci_register_bar(pdev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &edu->mmio);

and it is clear that properties of the BAR are hardware defined, e.g. the BAR number 0, has type memory PCI_BASE_ADDRESS_SPACE_MEMORY, and the memory region is 1MiB long 1 << 20.