Desculpe, mas a especulação na resposta escolhida é enganosa e deixa de fora o aspecto mais importante, que é a tradução de endereços por meio de tabelas de páginas.
É verdade que quando qualquer máquina compatível com PC inicializa, ela inicia em "modo real". E os sistemas operacionais modernos de 32 bits no x86 são executados no "modo protegido", que inclui o endereçamento segmentado, conforme definido pelo GDT. No entanto, eles também habilitam a tradução de endereços baseada na tabela de páginas configurando o bit PG (paginação), bit 31, no CR0. Isso nunca é desligado durante a vida útil do sistema operacional.
Além disso, na maioria dos sistemas operacionais modernos de 32 bits, o endereçamento segmentado baseado em GDT é essencialmente ignorado: Todos os GDTEs comumente usados são configurados com endereço base 0, tamanho 4 bilhões de bytes. Assim, embora a MMU passe pelos movimentos de adicionar o segmento relevante "endereço base" ao "deslocamento" que vem da instrução, isso é efetivamente um não operacional. Um conjunto diferente de GDTEs é usado para o anel 0 vs o anel 3, mas todos eles têm o mesmo endereço e tamanho base. Os campos "nível de privilégio" (0 vs 3) são sobre tudo o que é diferente. Isso permite que o bit de "acesso privilegiado" nas entradas da tabela de páginas seja efetivo, permitindo que a memória seja protegida para o modo kernel ou o acesso ao modo kernel + usuário, página por página. Isso não é possível com descritores de segmento; eles são muito grosseiros.
Em CPUs x64, o mecanismo de segmentação desaparece essencialmente no modo longo. A tradução de endereços baseada em tabelas de páginas, é claro, ainda acontece enquanto o bit PG é definido, o que acontece durante a vida útil do sistema operacional. A MMU é mais enfaticamente não desabilitada enquanto no modo kernel, nem o "SO" (ou qualquer coisa) usa mapeamento 1: 1 entre endereços virtuais e físicos.
Os acessos a endereços físicos conhecidos, como aqueles atribuídos a periféricos semelhantes a PCI, são feitos alocando endereços virtuais não utilizados e configurando as entradas correspondentes da tabela de páginas com os números de página física necessários. Código em drivers de dispositivo, em seguida, usa os endereços virtuais.
Sim, o DMA funciona principalmente em endereços físicos. Um controlador de DMA estúpido / barato na verdade apenas transfere para um buffer fisicamente contíguo com um determinado endereço inicial e comprimento. Para suportar tais dispositivos, o sistema operacional ou o driver de dispositivo alocará "buffers de retorno" fisicamente contíguos para o dispositivo DMA acessar e copiar dados entre eles e o buffer do usuário.
Controladores DMA inteligentes / mais caros podem manipular buffers que ocupam intervalos não contíguos de endereços físicos (referido como "mapeamento de dispersão-coleta"). Estes são muito preferidos para dispositivos de alto desempenho.
Um IOMMU pode permitir que controladores DMA estúpidos / baratos acessem um buffer fisicamente descontínuo como se fosse contíguo. No entanto, as plataformas com IOMMUs ainda não são onipresentes o suficiente para dizer "sua plataforma deve ter um IOMMU para o nosso sistema operacional". Portanto, no momento, as IOMMUs são usadas principalmente por monitores de máquinas virtuais.