Как ядро ​​Linux устанавливает PCI BAR, чтобы не было конфликта адресов? - PullRequest
2 голосов
/ 17 января 2020

Насколько я понимаю (что вполне может быть ошибочным), каждое PCI-устройство знает, сколько (размер) адресного пространства iomem / ioport оно хочет получить, но не знает, где (смещение). Только B IOS или ОС могут сообщить устройству, где это место должно быть, потому что кто-то должен общаться со всеми устройствами PCI и координировать свои запросы адресов iomem / ioport allo c, чтобы распределенные адреса не перекрывались, и эта координация происходит во время загрузки или при событии горячего подключения, или во время pci rescan . Однако в коде ядра Linux я нахожу только функцию (pci_read_bases), которая считывает информацию BAR и устанавливает соответственно pci_dev & iomem_resource / ioport_resource, не меняя БАРы. Итак, вопросы:

  1. Может ли ОС (Linux kernel) изменить BAR? Или только B IOS может сделать это перед загрузкой ОС?
  2. Если ядро ​​может изменить BAR, где находится лог c для координации распределения адресов? (Я видел такие функции, как pbus_assign_resources_sorted, но мне кажется, что эта функция только отображает существующие BAR в объекты ядра, такие как iomem_resource, не изменяя BAR)

1 Ответ

1 голос
/ 18 января 2020

Для обычного распределения c B IOS записывает BAR, а ядро ​​читает их при загрузке. Что интересно, так это динамически назначаемые устройства, такие как «горячее» подключение карт NVMe. В этом случае B IOS должен зарезервировать диапазон на случай, если подключено устройство, которого не было во время загрузки или оно больше, чем удаленное. Ядро получает прерывание и должно прочитать новые значения BAR и добавить их в адресное пространство. См. Например nvme_remap_bar https://elixir.bootlin.com/linux/v5.4/source/drivers/nvme/host/pci.c#L1649

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...