Por que os processadores x86 usam apenas 2 de 4 toques?

12

Portanto, os sistemas x86 baseados em Linux ou Windows usam apenas o anel 0 para o modo kernel e o anel 3 para o modo usuário. Por que os processadores distinguem até quatro anéis diferentes se todos acabarem usando apenas dois deles? E isso mudou na arquitetura AMD64?

    
por AdHominem 09.04.2016 / 17:16

1 resposta

14

Existem dois motivos principais.

A primeira razão é que, embora as CPUs x86 ofereçam quatro anéis de proteção de memória, a granularidade de proteção oferecida por ela é apenas no nível por segmento. Ou seja, cada segmento pode ser definido para um anel específico ("nível de privilégio") de 0 a 3, juntamente com outras proteções, como desativado por gravação. Mas não há muitos descritores de segmento disponíveis. A maioria dos sistemas operacionais gostaria de ter uma granularidade muito mais fina de proteção de memória. Como ... para páginas individuais.

Portanto, insira a proteção com base nas entradas da tabela de páginas (PTEs). A maioria, se não todos os modernos sistemas operacionais x86, mais ou menos ignoram o mecanismo de segmentação (tanto quanto podem, de qualquer forma) e contam com a proteção baseada em PTE. Isso é especificado pelos bits de sinalização, que são os 12 bits mais baixos em cada PTE - mais o bit 63 em CPUs que suportam no-execute. Há um PTE para cada página, que normalmente é 4K.

Um desses bits de bandeira é chamado de bit "privilegiado". Este bit controla se o processador deve ou não estar em um dos níveis "privilegiados" para acessar a página. Os níveis "privilegiados" são PL 0, 1 e 2. Mas é apenas um bit, portanto, no nível de proteção página por página, o número de "modos" disponíveis no que diz respeito à proteção de memória é apenas dois: uma página pode ser acessível a partir do modo não privilegiado ou não. Daí apenas dois anéis.

Para ter quatro anéis possíveis para cada página, eles precisariam ter dois bits de proteção em cada entrada da tabela de páginas, para codificar um dos quatro números de toque possíveis (assim como os descritores de segmento). Eles não.

O segundo motivo é o objetivo da portabilidade do sistema operacional. Não é apenas sobre x86; O Unix nos ensinou que um sistema operacional poderia ser relativamente portátil para arquiteturas de múltiplos processadores, e que isso era uma coisa boa. E alguns processadores suportam apenas dois toques. Por não depender de múltiplos toques na arquitetura, os implementadores do SO tornaram os SOs mais portáteis.

Existe uma terceira razão específica para o desenvolvimento do Windows NT. Os designers de NT (David Cutler e sua equipe, que a Microsoft contratou para longe da DEC Western Region Labs) tiveram uma extensa experiência anterior em VMS; Na verdade, Cutler e alguns dos outros estavam entre os designers originais da VMS. E o processador VAX para o qual o VMS foi projetado (e vice-versa) tem quatro toques. O VMS usa quatro toques. (Na verdade, o VAX tem quatro bits de proteção no PTE, permitindo combinações como "somente leitura do modo de usuário, mas gravável do anel 2 e interno". Mas eu discordo.)

Mas os componentes executados nos anéis 1 e 2 do VMS (Record Management Services e CLI, resp.) ficaram de fora do design do NT. O Ring 2 no VMS realmente não tinha a ver com a segurança do sistema operacional, mas sim com a preservação do ambiente de CLI do usuário de um programa para outro, e o Windows NT simplesmente não tinha esse conceito; o CLI é executado como um processo comum. Quanto ao anel 1 do VMS, o código RMS no anel 1 teve que chamar o anel 0 com bastante frequência e as transições de anel são caras. Acabou sendo muito mais eficiente simplesmente ir ao ring 0 e terminar com ele em vez de ter muitas transições de ring 0 dentro do código do ring 1. (Novamente - não que o NT tenha algo parecido com o RMS, de qualquer forma).

Mas por que eles estão lá, então? Por que o x86 implementou quatro toques enquanto os SOs não os usavam - você está falando de SOs de design muito mais recente que o x86. Muitos dos recursos de "programação do sistema" do x86 foram projetados muito antes que o NT ou os verdadeiros kernels Unix-ish fossem implementados nele, e eles realmente não sabiam o que os SOs usariam. (Não foi até recebermos o paging no x86 - que não apareceu até o 80386 - que nós poderíamos implementar os verdadeiros kernels do tipo Unix-ish ou VMS sem repensar o gerenciamento de memória do zero .)

Não apenas os sistemas operacionais x86 modernos ignoram a segmentação (eles apenas configuram os segmentos C, D e S com endereço 0 e tamanho de 4 GB; os segmentos F e G às vezes são usados para apontar para as principais estruturas de dados do SO) , eles também ignoram amplamente coisas como "segmentos do estado da tarefa". O mecanismo TSS foi claramente projetado para troca de contexto de thread, mas ele tem muitos efeitos colaterais, então os sistemas operacionais x86 modernos fazem isso "manualmente". A única vez que o NT x86 altera as tarefas de hardware, por exemplo, é para algumas condições verdadeiramente excepcionais, como uma exceção de falha dupla.

Re x64, muitos desses recursos em desuso foram deixados de fora. (Para seu crédito, a AMD conversou com as equipes de kernel do sistema operacional e perguntou do que precisava a partir do x86, o que eles não precisavam ou não queriam e o que eles gostariam de adicionar.) Os segmentos em x64 só existem no que pode ser chamado de forma vestigial, a comutação de estado da tarefa não existe, etc. E os SOs continuam a usar apenas dois toques.

    
por 12.04.2016 / 17:49