Qual é a diferença entre os modos de usuário e kernel em sistemas operacionais?

104

Quais são as diferenças entre o modo de usuário e o modo de kernel, por que e como você ativa qualquer um deles e quais são seus casos de uso?

Alex
fonte
1
Possível duplicata de Qual é a diferença entre o espaço do kernel e o espaço do usuário?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
@ CiroSantilli709 大 抓捕 六四 事件 法轮功 uma pergunta que foi feita há 7 anos não pode ser fechada como uma duplicata de uma pergunta feita há 6 anos. Se forem realmente duplicatas, o fechamento deve ser o contrário.
Salvador Dali
2
@SalvadorDali oi, o consenso atual é fechar por "qualidade": meta.stackexchange.com/questions/147643/… Como "qualidade" não é mensurável, eu apenas considero votos positivos . ;-) Provavelmente se trata de qual pergunta atingiu as melhores palavras-chave newb do Google no título. Recomendo que você simplesmente copie sua resposta com um aviso de isenção de responsabilidade adicionado na parte inferior e um link deste, para o caso de fechar.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respostas:

143
  1. Modo Kernel

    No modo Kernel, o código em execução tem acesso completo e irrestrito ao hardware subjacente. Ele pode executar qualquer instrução da CPU e fazer referência a qualquer endereço de memória. O modo kernel é geralmente reservado para as funções de nível mais baixo e mais confiáveis ​​do sistema operacional. As falhas no modo kernel são catastróficas; eles irão parar o PC inteiro.

  2. Modo de usuário

    No modo de usuário, o código em execução não tem capacidade de acessar diretamente o hardware ou a memória de referência. O código em execução no modo de usuário deve delegar às APIs do sistema para acessar o hardware ou a memória. Devido à proteção proporcionada por este tipo de isolamento, as falhas no modo de usuário são sempre recuperáveis. A maior parte do código em execução em seu computador será executada no modo de usuário.

Consulte Mais informação

Compreendendo o modo de usuário e kernel

Rahul
fonte
Gostaria de saber quando a CPU está executando o código do sistema operacional, em qual modo o processador está?
JackieLam
2
@JackieLam: Deve estar no modo kernel.
kadina
Então, por si só, para executar um processo de espaço do usuário , ele deve ser mapeado para o espaço do kernel ?
roottraveller
@rahul Duvido que a memória de referência possa ser obtida pelo modo de usuário ou que a manipulação de dados mais simples resulte em uma mudança de modo cara em uma linguagem como java.
maki XIE
48

Esses são dois modos diferentes nos quais seu computador pode operar. Antes disso, quando os computadores eram como uma grande sala, se algo travasse, o computador inteiro seria interrompido. Portanto, os arquitetos de computador decidem mudá-lo. Os microprocessadores modernos implementam em hardware pelo menos 2 estados diferentes.

Modo de usuário:

  • modo onde todos os programas do usuário são executados. Ele não tem acesso a RAM e hardware. A razão para isso é porque se todos os programas rodassem no modo kernel, eles seriam capazes de sobrescrever a memória uns dos outros. Se precisar acessar qualquer um desses recursos - ele faz uma chamada para a API subjacente. Cada processo iniciado pelo Windows, exceto o processo do sistema, é executado no modo de usuário.

Modo kernel:

  • modo onde todos os programas do kernel são executados (drivers diferentes). Ele tem acesso a todos os recursos e hardware subjacente. Qualquer instrução da CPU pode ser executada e todos os endereços de memória podem ser acessados. Este modo é reservado para motoristas que operam no nível mais baixo

Como a troca ocorre.

A mudança do modo de usuário para o modo kernel não é feita automaticamente pela CPU. A CPU é interrompida por interrupções (temporizadores, teclado, E / S). Quando ocorre uma interrupção, a CPU para de executar o programa em execução no momento, alterna para o modo kernel, executa o manipulador de interrupção. Este manipulador salva o estado da CPU, executa suas operações, restaura o estado e retorna ao modo de usuário.

http://en.wikibooks.org/wiki/Windows_Programming/User_Mode_vs_Kernel_Mode

http://tldp.org/HOWTO/KernelAnalysis-HOWTO-3.html

http://en.wikipedia.org/wiki/Direct_memory_access

http://en.wikipedia.org/wiki/Interrupt_request

Salvador Dalí
fonte
Gostaria de saber quando a CPU está executando o código do sistema operacional, em qual modo o processador está?
JackieLam
1
@JackieLam: modo kernel
Apurv Nerlekar
10

Um processador em um computador com Windows tem dois modos diferentes: modo de usuário e modo kernel. O processador alterna entre os dois modos dependendo do tipo de código em execução no processador. Os aplicativos são executados no modo de usuário e os componentes principais do sistema operacional são executados no modo kernel. Embora muitos drivers sejam executados no modo kernel, alguns drivers podem ser executados no modo do usuário.

Quando você inicia um aplicativo no modo de usuário, o Windows cria um processo para o aplicativo. O processo fornece ao aplicativo um espaço de endereço virtual privado e uma tabela de manipulação privada. Como o espaço de endereço virtual de um aplicativo é privado, um aplicativo não pode alterar os dados que pertencem a outro aplicativo. Cada aplicativo é executado isoladamente e, se um aplicativo falhar, a falha será limitada a esse aplicativo. Outros aplicativos e o sistema operacional não são afetados pela falha.

Além de ser privado, o espaço de endereço virtual de um aplicativo de modo de usuário é limitado. Um processador em execução no modo de usuário não pode acessar endereços virtuais reservados para o sistema operacional. Limitar o espaço de endereço virtual de um aplicativo de modo de usuário impede que o aplicativo altere, e possivelmente danifique, dados críticos do sistema operacional.

Todo o código executado no modo kernel compartilha um único espaço de endereço virtual. Isso significa que um driver de modo kernel não é isolado de outros drivers e do próprio sistema operacional. Se um driver de modo kernel acidentalmente gravar no endereço virtual errado, os dados que pertencem ao sistema operacional ou a outro driver podem ser comprometidos. Se um driver do modo kernel travar, todo o sistema operacional travará.

Se você for um usuário do Windows uma vez, acesse este link, você obterá mais.

Comunicação entre modo de usuário e modo kernel

Sangeen
fonte
6

Os anéis de CPU são a distinção mais clara

No modo x86 protegido, a CPU está sempre em um dos 4 anéis. O kernel Linux usa apenas 0 e 3:

  • 0 para kernel
  • 3 para usuários

Esta é a definição mais difícil e rápida de kernel vs userland.

Por que o Linux não usa os anéis 1 e 2: Anéis de privilégio da CPU: Por que os anéis 1 e 2 não são usados?

Como o anel atual é determinado?

O anel atual é selecionado por uma combinação de:

  • tabela descritor global: uma tabela na memória de entradas GDT, e cada entrada tem um campo Privlque codifica o anel.

    A instrução LGDT define o endereço para a tabela do descritor atual.

    Veja também: http://wiki.osdev.org/Global_Descriptor_Table

  • o segmento registra CS, DS, etc., que apontam para o índice de uma entrada no GDT.

    Por exemplo, CS = 0significa que a primeira entrada do GDT está atualmente ativa para o código em execução.

O que cada anel pode fazer?

O chip da CPU é fisicamente construído para que:

  • anel 0 pode fazer qualquer coisa

  • o anel 3 não pode executar várias instruções e gravar em vários registradores, mais notavelmente:

    • não pode mudar seu próprio anel! Caso contrário, ele poderia se definir para tocar 0 e os toques seriam inúteis.

      Em outras palavras, não pode modificar o descritor de segmento atual , que determina o anel atual.

    • não é possível modificar as tabelas de página: Como funciona a paginação x86?

      Em outras palavras, não pode modificar o registro CR3 e a própria paginação evita a modificação das tabelas de página.

      Isso evita que um processo veja a memória de outros processos por razões de segurança / facilidade de programação.

    • não pode registrar manipuladores de interrupção. Eles são configurados gravando em locais de memória, o que também é evitado pela paginação.

      Os manipuladores são executados no anel 0 e violam o modelo de segurança.

      Em outras palavras, não pode usar as instruções LGDT e LIDT.

    • não pode executar instruções IO como ine out, portanto, ter acessos de hardware arbitrários.

      Caso contrário, por exemplo, as permissões de arquivo seriam inúteis se qualquer programa pudesse ler diretamente do disco.

      Mais precisamente, graças a Michael Petch : é realmente possível para o sistema operacional permitir instruções IO no anel 3, isso é na verdade controlado pelo segmento de estado da tarefa .

      O que não é possível é que o anel 3 dê a si mesmo permissão para fazê-lo, se antes não o tivesse.

      O Linux sempre proíbe isso. Consulte também: Por que o Linux não usa a alternância de contexto de hardware por meio do TSS?

Como os programas e sistemas operacionais fazem a transição entre os anéis?

  • quando a CPU é ligada, ela começa a rodar o programa inicial no anel 0 (bem mais ou menos, mas é uma boa aproximação). Você pode pensar que este programa inicial é o kernel (mas normalmente é um gerenciador de inicialização que então chama o kernel ainda no anel 0 ).

  • quando um processo de usuário quer que o kernel faça algo por ele, como gravar em um arquivo, ele usa uma instrução que gera uma interrupção, como int 0x80ousyscall para sinalizar o kernel. x86-64 Linux syscall hello world example:

    .data
    hello_world:
        .ascii "hello world\n"
        hello_world_len = . - hello_world
    .text
    .global _start
    _start:
        /* write */
        mov $1, %rax
        mov $1, %rdi
        mov $hello_world, %rsi
        mov $hello_world_len, %rdx
        syscall
    
        /* exit */
        mov $60, %rax
        mov $0, %rdi
        syscall
    

    compilar e executar:

    as -o hello_world.o hello_world.S
    ld -o hello_world.out hello_world.o
    ./hello_world.out
    

    GitHub upstream .

    Quando isso acontece, a CPU chama um manipulador de retorno de chamada de interrupção que o kernel registrou no momento da inicialização. Aqui está um exemplo concreto de baremetal que registra um manipulador e o usa .

    Este manipulador é executado no anel 0, que decide se o kernel permitirá esta ação, realizará a ação e reiniciará o programa do espaço do usuário no anel 3. x86_64

  • quando a execchamada do sistema é usada (ou quando o kernel irá iniciar/init ), o kernel prepara os registros e a memória do novo processo de usuário, então ele salta para o ponto de entrada e muda a CPU para o anel 3

  • Se o programa tentar fazer algo perverso, como escrever em um registro proibido ou endereço de memória (por causa da paginação), a CPU também chama algum manipulador de retorno de chamada do kernel no anel 0.

    Mas como o userland era perverso, o kernel pode matar o processo dessa vez ou dar a ele um aviso com um sinal.

  • Quando o kernel inicializa, ele configura um relógio de hardware com alguma frequência fixa, que gera interrupções periodicamente.

    Este relógio de hardware gera interrupções que rodam no anel 0 e permitem que ele agende quais processos do espaço do usuário serão ativados.

    Dessa forma, o agendamento pode acontecer mesmo que os processos não estejam fazendo chamadas de sistema.

Qual é a vantagem de ter vários anéis?

Existem duas vantagens principais em separar kernel e userland:

  • é mais fácil fazer programas, pois você tem mais certeza de que um não interferirá no outro. Por exemplo, um processo de usuário não precisa se preocupar em sobrescrever a memória de outro programa por causa da paginação, nem em colocar o hardware em um estado inválido para outro processo.
  • é mais seguro. Por exemplo, permissões de arquivo e separação de memória podem impedir que um aplicativo hacker leia seus dados bancários. Isso supõe, é claro, que você confia no kernel.

Como brincar com isso?

Criei uma configuração bare metal que deve ser uma boa maneira de manipular anéis diretamente: https://github.com/cirosantilli/x86-bare-metal-examples

Eu não tive paciência para fazer um exemplo de userland, infelizmente, mas eu fui mais longe na configuração de paginação, então userland deve ser viável. Adoraria ver um pedido de pull.

Alternativamente, os módulos do kernel do Linux são executados no anel 0, então você pode usá-los para experimentar operações privilegiadas, por exemplo, ler os registros de controle: Como acessar os registros de controle cr0, cr2, cr3 de um programa? Obtendo falha de segmentação

Aqui está uma configuração conveniente do QEMU + Buildroot para testá-la sem matar o seu host.

A desvantagem dos módulos do kernel é que outros kthreads estão em execução e podem interferir em seus experimentos. Mas, em teoria, você pode assumir o controle de todos os manipuladores de interrupção com seu módulo do kernel e possuir o sistema, o que seria um projeto interessante na verdade.

Anéis negativos

Embora os anéis negativos não sejam realmente mencionados no manual da Intel, na verdade existem modos de CPU que têm mais recursos do que o próprio anel 0 e, portanto, são adequados para o nome "anel negativo".

Um exemplo é o modo hipervisor usado na virtualização.

Para mais detalhes, consulte:

BRAÇO

No ARM, os anéis são chamados de Níveis de Exceção, mas as idéias principais permanecem as mesmas.

Existem 4 níveis de exceção no ARMv8, comumente usados ​​como:

  • EL0: userland

  • EL1: kernel ("supervisor" na terminologia ARM).

    Entrado com a svcinstrução (SuperVisor Call), anteriormente conhecida como swi antes da montagem unificada , que é a instrução usada para fazer chamadas de sistema Linux. Hello world ARMv8 example:

    ola.S

    .text
    .global _start
    _start:
        /* write */
        mov x0, 1
        ldr x1, =msg
        ldr x2, =len
        mov x8, 64
        svc 0
    
        /* exit */
        mov x0, 0
        mov x8, 93
        svc 0
    msg:
        .ascii "hello syscall v8\n"
    len = . - msg
    

    GitHub upstream .

    Teste-o com QEMU no Ubuntu 16.04:

    sudo apt-get install qemu-user gcc-arm-linux-gnueabihf
    arm-linux-gnueabihf-as -o hello.o hello.S
    arm-linux-gnueabihf-ld -o hello hello.o
    qemu-arm hello
    

    Aqui está um exemplo concreto de baremetal que registra um manipulador SVC e faz uma chamada SVC .

  • EL2: hipervisores , por exemplo Xen .

    Inserido com a hvcinstrução (HyperVisor Call).

    Um hipervisor está para um sistema operacional, o que um sistema operacional está para o usuário.

    Por exemplo, o Xen permite que você execute vários sistemas operacionais, como Linux ou Windows, no mesmo sistema ao mesmo tempo, e isola os sistemas operacionais uns dos outros para segurança e facilidade de depuração, assim como o Linux faz para programas no ambiente do usuário.

    Os hipervisores são uma parte importante da infraestrutura de nuvem atual: eles permitem que vários servidores sejam executados em um único hardware, mantendo o uso do hardware sempre próximo a 100% e economizando muito dinheiro.

    A AWS, por exemplo, usou o Xen até 2017, quando sua mudança para KVM virou notícia .

  • EL3: mais um nível. Exemplo TODO.

    Inserido com a smcinstrução (Secure Mode Call)

O modelo de referência de arquitetura ARMv8 DDI 0487C.a - Capítulo D1 - O modelo do programador de nível de sistema AArch64 - Figura D1-1 ilustra isso lindamente:

insira a descrição da imagem aqui

A situação do ARM mudou um pouco com o advento do ARMv8.1 Virtualization Host Extensions (VHE) . Esta extensão permite que o kernel seja executado em EL2 de forma eficiente:

insira a descrição da imagem aqui

O VHE foi criado porque as soluções de virtualização no kernel Linux, como KVM, ganharam terreno em relação ao Xen (veja, por exemplo, a mudança da AWS para KVM mencionada acima), porque a maioria dos clientes só precisa de VMs Linux e, como você pode imaginar, estar tudo em um único projeto, KVM é mais simples e potencialmente mais eficiente do que Xen. Portanto, agora o kernel do host Linux atua como o hipervisor nesses casos.

Observe como o ARM, talvez devido ao benefício da percepção tardia, tem uma convenção de nomenclatura melhor para os níveis de privilégio do que x86, sem a necessidade de níveis negativos: 0 sendo o mais baixo e 3 o mais alto. Os níveis mais altos tendem a ser criados com mais frequência do que os mais baixos.

O EL atual pode ser consultado com a MRSinstrução: qual é o modo de execução / nível de exceção atual, etc?

O ARM não exige que todos os níveis de exceção estejam presentes para permitir implementações que não precisam do recurso para salvar a área do chip. ARMv8 "Níveis de exceção" diz:

Uma implementação pode não incluir todos os níveis de exceção. Todas as implementações devem incluir EL0 e EL1. EL2 e EL3 são opcionais.

O QEMU, por exemplo, é padronizado como EL1, mas EL2 e EL3 podem ser habilitados com opções de linha de comando: qemu-system-aarch64 inserindo el1 ao emular a53 power up

Trechos de código testados no Ubuntu 18.10.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fonte
1
Uma vez que esta pergunta não é específica para nenhum sistema operacional ine outestá disponível para o anel 3. O TSS pode apontar para uma tabela de permissão IO na tarefa atual que concede acesso de leitura / gravação a todas as portas ou portas específicas.
Michael Petch
É claro que você define os bits IOPL para o valor 3, então o programa ring 3 tem acesso total à porta e as permissões TSS IO não se aplicam.
Michael Petch
@MichaelPetch obrigado, não sabia disso. Eu atualizei a resposta.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
5

Vou fazer uma tentativa no escuro e acho que você está falando sobre o Windows. Resumindo, o modo kernel tem acesso total ao hardware, mas o modo usuário não. Por exemplo, muitos, se não a maioria, dos drivers de dispositivo são escritos no modo kernel porque precisam controlar os detalhes mais precisos de seu hardware.

Veja também este wikibook .

Mark Rushakoff
fonte
2
Isso é importante para você como um programador porque os bugs do kernel tendem a causar estragos muito piores do que você está acostumado. Uma razão para a distinção kernel / usuário é que o kernel pode monitorar / controlar recursos críticos do sistema e proteger cada usuário dos outros. É um pouco simplificado, mas ainda útil, para lembrar a você mesmo que os bugs do usuário costumam ser irritantes, mas os bugs do kernel tendem a derrubar a máquina inteira.
Adam Liss
3

Outras respostas já explicaram a diferença entre modo de usuário e kernel. Se você realmente deseja entrar em detalhes, deve obter uma cópia do Windows Internals , um excelente livro escrito por Mark Russinovich e David Solomon que descreve a arquitetura e os detalhes internos dos vários sistemas operacionais Windows.

Dirk Vollmar
fonte
2

o que

Basicamente, a diferença entre o kernel e os modos do usuário não depende do sistema operacional e é alcançada apenas restringindo algumas instruções para serem executadas apenas no modo kernel por meio do design de hardware. Todas as outras finalidades, como proteção de memória, podem ser realizadas apenas por essa restrição.

Quão

Isso significa que o processador vive no modo kernel ou no modo do usuário. Usando alguns mecanismos, a arquitetura pode garantir que sempre que for alternado para o modo kernel, o código do sistema operacional será buscado para ser executado.

Por quê

Tendo essa infraestrutura de hardware, isso pode ser alcançado em sistemas operacionais comuns:

  • Protegendo os programas do usuário de acessar toda a memória, para não permitir que os programas sobrescrevam o sistema operacional, por exemplo,
  • impedir que programas de usuário executem instruções sensíveis, como aquelas que alteram os limites do ponteiro da memória da CPU, para não permitir que os programas quebrem seus limites de memória, por exemplo.
Ali Asgari
fonte