При запуске компьютера BIOS или операционная система проверяет каждое устройство PCI, чтобы узнать, сколько адресного пространства ему нужно. Затем он выделяет соответствующее пространство и сообщает каждому устройству PCI, где начинается его пространство, чтобы устройство PCI могло отвечать на запросы чтения и записи в этом диапазоне.
Мой вопрос: почему всем устройствам нужно выделять блоки из одного и того же адресного пространства? Почему бы не дать каждому устройству собственное адресное пространство?
На печатной плате уже существует «внеполосный» способ различения устройств PCI: линия IDSEL. Это то, что используется во время перечисления PCI, до того, как каждому устройству будет выделено пространство. Так почему бы не использовать это также и для доступа после перечисления, и не сохранить некоторую логику декодирования на устройстве PCI? Это было бы как-то медленнее, или что-то в этом роде?
решение1
Как правило, они этого не делают.нуждатьсядля совместного использования одного и того же адресного пространства. Разделение адресных пространств устройства — это именно то, для чего предназначен IOMMU, и это может быть полезно по ряду причин:
- Он может безопасно разрешить виртуальной машине прямой доступ к физическому оборудованию с помощью собственных драйверов.
- Он отделяет возможности адресации устройства от физического адресного пространства. Другими словами, он позволяет иметь устройства, которые могут выполнять только 32-битную адресацию, доступ к данным в любом месте физической памяти, даже выше первого 4G.
- Это позволяет более тщательно изолировать устройства друг от друга, что может значительно повысить безопасность системы.
Что касается того, почему это не поведение по умолчанию и почему линия IDSEL не используется для этого, я не могу сказать, так как не очень хорошо знаю историю разработок PCI. Моя первая догадка заключается в том, что изначально это было сделано для того, чтобы было проще портировать драйверы для карт ISA на PCI (ISA предполагает плоское общее адресное пространство). Кроме того, IOMMU — не самая простая в проектировании часть оборудования, и только недавно они стали широко доступны на платформах x86 (и до сих пор не гарантированы, многие чипы Intel до сих пор их не имеют, и многие недорогие чипы AMD тоже).
Однако стоит отметить, что при использовании PCI Express на самом деле есть преимущество в совместном использовании адресного пространства между устройствами, а именно то, что он позволяет выполнять передачу данных с устройства на устройство (хотя большинство платформ не поддерживают это должным образом), что может быть очень полезно в крупных сетевых конфигурациях, использующих RDMA (вы можете получать данные с удаленных устройств напрямую, без необходимости посредничества ОС удаленной системы после настройки передачи).
решение2
Для систем x86 сам ЦП может получить доступ только к двум адресным пространствам: обычному адресному пространству памяти и адресному пространству ввода-вывода. Другие системы могут иметь только одно адресное пространство (например, ARM, powerpc и т. д.). Эти два адресных пространства разделены с точки зрения устройств PCI — для доступа к каждому адресному пространству используются разные команды, а мосты имеют отдельные регистры конфигурации для каждого адресного пространства. Однако, поскольку ЦП может получить доступ только к этим двум адресным пространствам, все подключенные устройства должны быть сопоставлены с этими двумя адресными пространствами. Так что это на самом деле не столько ограничение PCI, сколько ограничение архитектуры остальной части системы.
Я также должен упомянуть, что когда разрабатывался PCI, не существовало такого понятия, как IOMMU, это относительно недавнее дополнение.