Tut mir leid, aber die Spekulation in der gewählten Antwort ist irreführend und lässt den wichtigsten Aspekt weg, nämlich die Adressübersetzung über Seitentabellen.
Es stimmt, dass beim Start einer PC-kompatiblen Maschine der "Real-Modus" gestartet wird. Und moderne 32-Bit-Betriebssysteme auf x86 laufen im "Protected Mode", zu dem die segmentierte Adressierung gemäß GDT gehört. Sie ermöglichen dann jedoch auch eine seitentabellenbasierte Adressumsetzung durch Setzen des PG (Paging) -Bits Bit 31 in CR0. Dies ist für die Dauer des Betriebssystems niemals deaktiviert.
In den meisten modernen 32-Bit-Betriebssystemen wird die GDT-basierte segmentierte Adressierung im Wesentlichen umgangen: Alle häufig verwendeten GDTEs werden mit der Basisadresse 0 und einer Größe von 4 Milliarden Byte eingerichtet. Obwohl die MMU jedoch die Bewegungen des Hinzufügens des relevanten Segments "Basisadresse" zu der "Verschiebung" durchführt, die von dem Befehl ausgeht, ist dies tatsächlich ein No-Op. Ein anderer Satz GDTEs wird für Ring 0 und Ring 3 verwendet, aber alle haben dieselbe Basisadresse und -größe. Die "Privileg Level" -Felder (0 vs 3) betreffen alles, was unterschiedlich ist. Dies ermöglicht, dass das Bit "privilegierter Zugriff" in den Seitentabelleneinträgen wirksam ist, wodurch der Speicher für den Kernelmodus oder den Benutzer- und Kernelmoduszugriff Seite für Seite geschützt werden kann. Das ist mit Segmentdeskriptoren nicht möglich. Sie sind viel zu grobkörnig.
Bei x64-CPUs verschwindet der Segmentierungsmechanismus im Langmodus im Wesentlichen. Die seitenbasierte Adressumsetzung geschieht natürlich immer noch, solange das PG-Bit gesetzt ist. Dies ist während der gesamten Lebensdauer des Betriebssystems der Fall. Die MMU ist im Kernelmodus nachdrücklich nicht deaktiviert, und die "SO" (oder irgendetwas) verwendet keine 1: 1-Zuordnung zwischen virtuellen und physischen Adressen.
Zugriffe auf bekannte physische Adressen, wie beispielsweise solche, die PCI-ähnlichen Peripheriegeräten zugewiesen sind, werden durch Zuweisen nicht verwendeter virtueller Adressen und Einrichten der entsprechenden Seitentabelleneinträge mit den erforderlichen physischen Seitennummern erreicht. Der Code in Gerätetreibern verwendet dann die virtuellen Adressen.
Ja, DMA arbeitet hauptsächlich mit physischen Adressen. Ein dummer / billiger DMA-Controller wird in der Tat einfach mit einer vorgegebenen Startadresse und Länge in einen physisch benachbarten Puffer übertragen. Um solche Geräte zu unterstützen, werden entweder das Betriebssystem oder der Gerätetreiber dem DMA-Gerät physikalisch benachbarte "Bounce-Puffer" zuweisen, auf die zugegriffen werden kann, und Daten zwischen diesem und dem Puffer des Benutzers zu kopieren.
Intelligente / teurere DMA-Controller können Puffer behandeln, die unzusammenhängende Bereiche physikalischer Adressen belegen (als "Scatter-Gather-Mapping" bezeichnet). Diese werden für Hochleistungsgeräte bevorzugt.
Eine IOMMU kann dummen / billigen DMA-Controllern den Zugriff auf einen physisch nicht zusammenhängenden Puffer ermöglichen, als wäre dieser zusammenhängend. Plattformen mit IOMMUs sind jedoch noch nicht allgegenwärtig genug, um zu sagen "Ihre Plattform muss eine IOMMU für unser Betriebssystem haben". Daher werden IOMMUs derzeit hauptsächlich von VM-Monitoren verwendet.