Что такое регистр базовых адресов (BAR) в PCIe?

после прохождения некоторых базовых документов я понял, что Регистр базовых адресов-это адресное пространство, к которому можно получить доступ по IP-адресу PCIe. IP PCIe может или передать данные в регистре низкопробного адреса или он может написать полученные данные дальше к ему.

Я прав? Или чего-то не хватает?

2 ответов


Я думаю, что это очень простой вопрос и я бы предложил читать:

регистр базового адреса (BAR) используется для:
- укажите, сколько памяти устройство хочет быть отображено в основную память, и
- после перечисления устройства он содержит (базовый) адрес, где отображается память блок начинается.

устройство может иметь до шести 32-разрядных баров или объединить два бара в 64-разрядный бар.


точка зрения ядра Linux

хороший способ узнать что-то, чтобы взаимодействовать с ним, так что давайте использовать ядро Linux для этого.

вот минимальный пример PCI на эмулируемом QEMU устройстве: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/366b1c1af269f56d6a7e6464f2862ba2bc368062/kernel_module/pci.c

первые 64 байта конфигурации PCI унифицированы as:

enter image description here

изображение из LDD3.

таким образом, мы можем видеть, что есть 6 баров. The страница wiki затем показывает содержимое каждого бара:

enter image description here

ширина области требует волшебной записи, однако:как определяется размер панели PCI / PCIe?

память настройка устройства PCI и дает информацию ядро.

каждый бар соответствует диапазону адресов, который служит отдельным каналом связи с устройством PCI.

длина каждой области определена оборудованием, и сообщена к программному обеспечению через регистры конфигурации.

каждая область также имеет дополнительные аппаратные свойства, кроме длины, в частности тип памяти:

  • IORESOURCE_IO: необходимо получить доступ с помощью inX и outX
  • IORESOURCE_MEM: необходимо получить доступ с ioreadX и iowriteX

несколько функций PCI ядра Linux принимают BAR в качестве параметра для определения того, какой канал связи должен использоваться, например:

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);

заглянув в исходный код устройства QEMU, мы видим, что устройства QEMU регистрируют эти регионы с помощью:

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);

и ясно, что свойства бара определены аппаратно, например, номер бара 0, имеет тип , и область памяти 1mib длиной 1 << 20.

см. также:http://wiki.osdev.org/PCI#Base_Address_Registers конечно.