Qual é a diferença entre o espaço do kernel e o espaço do usuário? Espaço, threads, processos e pilha do kernel significam a mesma coisa? Além disso, por que precisamos dessa diferenciação?
143
Qual é a diferença entre o espaço do kernel e o espaço do usuário? Espaço, threads, processos e pilha do kernel significam a mesma coisa? Além disso, por que precisamos dessa diferenciação?
Respostas:
A resposta realmente simplificada é que o kernel é executado no espaço do kernel e os programas normais são executados no espaço do usuário. O espaço do usuário é basicamente uma forma de sandbox - restringe os programas do usuário para que eles não possam mexer na memória (e outros recursos) pertencentes a outros programas ou ao kernel do SO. Isso limita (mas geralmente não elimina completamente) sua capacidade de fazer coisas ruins, como bater na máquina.
O kernel é o núcleo do sistema operacional. Normalmente, ele tem acesso total a toda a memória e hardware da máquina (e tudo o mais na máquina). Para manter a máquina o mais estável possível, você normalmente deseja que apenas o código mais confiável e bem testado seja executado no modo / espaço do kernel.
A pilha é apenas mais uma parte da memória; portanto, é naturalmente segregada junto com o restante da memória.
fonte
A memória de acesso aleatório (RAM) pode ser logicamente dividida em duas regiões distintas, a saber: o espaço do kernel e o espaço do usuário ( os endereços físicos da RAM não são realmente divididos apenas os endereços virtuais , tudo isso implementado pela MMU )
O kernel é executado na parte da memória com direito a ele. Esta parte da memória não pode ser acessada diretamente pelos processos dos usuários normais, enquanto o kernel pode acessar todas as partes da memória. Para aceder a alguma parte do kernel, os processos de usuário tem que usar o sistema pré-definido chamadas ou seja
open
,read
,write
etc. Além disso, asC
funções de biblioteca comoprintf
chamada a chamada de sistemawrite
, por sua vez.As chamadas do sistema atuam como uma interface entre os processos do usuário e os processos do kernel. Os direitos de acesso são colocados no espaço do kernel para impedir que os usuários mexam com o kernel, sem o saber.
Portanto, quando ocorre uma chamada do sistema, uma interrupção do software é enviada ao kernel. A CPU pode entregar o controle temporariamente para a rotina de manipulador de interrupção associada. O processo do kernel que foi interrompido pela interrupção é retomado depois que a rotina do manipulador de interrupções termina seu trabalho.
fonte
Espaço do kernel e espaço virtual são conceitos de memória virtual ... não significa que o Ram (sua memória real) seja dividido em kernel e espaço do usuário. Cada processo recebe memória virtual dividida em kernel e espaço do usuário.
Dizendo "A memória de acesso aleatório (RAM) pode ser dividida em duas regiões distintas, a saber - o espaço do kernel e o espaço do usuário". está errado.
& sobre a coisa "espaço do kernel vs espaço do usuário"
Quando um processo é criado e sua memória virtual é dividida em espaço do usuário e espaço do kernel, onde a região do espaço do usuário contém dados, código, pilha, pilha do processo e o espaço do kernel contém itens como a tabela de páginas do processo , estruturas de dados do kernel e código do kernel etc. Para executar o código do espaço do kernel, o controle deve mudar para o modo kernel (usando a interrupção do software 0x80 para chamadas do sistema) e a pilha do kernel é basicamente compartilhada entre todos os processos atualmente em execução no espaço do kernel.
fonte
Os anéis da CPU são a distinção mais clara
No modo protegido x86, a CPU está sempre em um dos quatro toques. O kernel do Linux usa apenas 0 e 3:
Esta é a definição mais rígida 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 é determinado o anel atual?
O anel atual é selecionado por uma combinação de:
tabela descritor global: uma tabela na memória de entradas GDT e cada entrada possui um campo
Privl
que codifica o anel.A instrução LGDT define o endereço para a tabela atual do descritor.
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 = 0
significa 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 registros, principalmente:
não pode mudar seu próprio anel! Caso contrário, poderia definir-se para tocar 0 e os anéis seriam inúteis.
Em outras palavras, não é possível modificar o descritor de segmento atual , que determina o anel atual.
Não é possível modificar as tabelas da página: Como funciona a paginação x86?
Em outras palavras, não é possível modificar o registro CR3 e a paginação em si impede a modificação das tabelas de páginas.
Isso impede que um processo veja a memória de outros processos por motivos de segurança / facilidade de programação.
não pode registrar manipuladores de interrupção. Esses são configurados gravando nos locais da memória, o que também é impedido pela paginação.
Os manipuladores executam no anel 0 e quebram o modelo de segurança.
Em outras palavras, não é possível usar as instruções LGDT e LIDT.
não pode executar instruções de E / S como
in
eout
, portanto, possui acessos de hardware arbitrários.Caso contrário, por exemplo, as permissões de arquivo seriam inúteis se algum programa pudesse ler diretamente do disco.
Mais precisamente graças a Michael Petch : é realmente possível que o sistema operacional permita instruções de E / S no anel 3; isso é realmente controlado pelo segmento de estado da tarefa .
O que não é possível é que o anel 3 se dê permissão para fazê-lo se não o tiver em primeiro lugar.
O Linux sempre o desaprova. Veja também: Por que o Linux não usa a opção de contexto de hardware via TSS?
Como os programas e sistemas operacionais fazem a transição entre os anéis?
quando a CPU está ligada, ele começa a executar o programa inicial no anel 0 (bem, mas é uma boa aproximação). Você pode pensar que esse programa inicial é o kernel (mas normalmente é um gerenciador de inicialização que chama o kernel ainda no anel 0 ).
quando um processo da terra do usuário deseja que o kernel faça algo como gravar em um arquivo, ele usa uma instrução que gera uma interrupção como
int 0x80
ousyscall
para sinalizar o kernel. x86-64 Linux syscall hello world example:compile e execute:
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 baremetal concreto que registra um manipulador e o utiliza .
Esse manipulador é executado no anel 0, que decide se o kernel permitirá essa ação, faça a ação e reinicie o programa userland no anel 3. x86_64
quando a
exec
chamada do sistema é usada (ou quando o kernel inicia/init
), o kernel prepara os registros e a memória do novo processo da terra do usuário, depois pula para o ponto de entrada e muda a CPU para tocar 3Se o programa tentar fazer algo malicioso, como gravar em um registro ou endereço de memória proibido (por causa da paginação), a CPU também chamará algum manipulador de retorno de chamada do kernel no anel 0.
Mas como a região do usuário foi malcriada, o kernel pode interromper o processo dessa vez ou avisar com um sinal.
Quando o kernel é inicializado, ele configura um relógio de hardware com alguma frequência fixa, o que gera interrupções periodicamente.
Esse relógio de hardware gera interrupções que executam o anel 0 e permite agendar quais processos da terra do usuário serão ativados.
Dessa forma, o agendamento pode ocorrer mesmo se os processos não estiverem fazendo nenhuma chamada do sistema.
Qual é o sentido de ter vários anéis?
Existem duas vantagens principais na separação do kernel e da terra do usuário:
Como brincar com isso?
Eu 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
Infelizmente, não tive a paciência de fazer um exemplo da terra do usuário, mas fui até a configuração de paginação, portanto a terra do usuário deve ser viável. Eu adoraria ver uma solicitação de recebimento.
Como alternativa, os módulos do kernel Linux são executados no anel 0, para que você possa 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á-lo sem matar o seu host.
A desvantagem dos módulos do kernel é que outros kthreads estão em execução e podem interferir nos seus experimentos. Mas, em teoria, você pode assumir todos os manipuladores de interrupção com o seu módulo do kernel e possuir o sistema, que seria realmente um projeto interessante.
Anéis negativos
Embora os anéis negativos não sejam realmente mencionados no manual da Intel, na verdade existem modos de CPU que possuem recursos adicionais que o próprio anel 0 e, portanto, são adequados para o nome "anel negativo".
Um exemplo é o modo hypervisor 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: terra do usuário
EL1: kernel ("supervisor" na terminologia do ARM).
Introduzida com a
svc
instrução (SuperVisor Call), anteriormente conhecida comoswi
assembly unificado , que é a instrução usada para fazer chamadas do sistema Linux. Olá, mundo, exemplo do ARMv8:ola.S
GitHub upstream .
Teste com o QEMU no Ubuntu 16.04:
Aqui está um exemplo baremetal concreto que registra um manipulador SVC e faz uma chamada SVC .
EL2: hipervisores , por exemplo, Xen .
Introduzido com a
hvc
instrução (chamada do HyperVisor).Um hipervisor é para um sistema operacional, o que é um sistema operacional para a terra do usuário.
Por exemplo, o Xen permite executar vários SOs como Linux ou Windows no mesmo sistema ao mesmo tempo, e isola os SOs uns dos outros para segurança e facilidade de depuração, assim como o Linux faz para programas da área de usuário.
Os hipervisores são uma parte essencial da infraestrutura de nuvem atual: eles permitem a execução de vários servidores em um único hardware, mantendo o uso de hardware sempre próximo de 100% e economizando muito dinheiro.
A AWS, por exemplo, usou o Xen até 2017, quando foi transferida para a KVM .
EL3: mais um nível. Exemplo TODO.
Introduzido com a
smc
instrução (Secure Mode Call)O Modelo de Referência de Arquitetura do ARMv8 DDI 0487C.a - Capítulo D1 - O Modelo do Programador de Nível de Sistema AArch64 - A Figura D1-1 ilustra isso de maneira bonita:
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 no EL2 com eficiência:
O VHE foi criado porque as soluções de virtualização no kernel do Linux, como o KVM, ganharam terreno com o Xen (veja, por exemplo, a mudança da AWS para o KVM mencionada acima), porque a maioria dos clientes precisa apenas de VMs Linux e, como você pode imaginar, estando em uma única projeto, o KVM é mais simples e potencialmente mais eficiente que o Xen. Portanto, agora o kernel do Linux host atua como hipervisor nesses casos.
Observe como o ARM, talvez devido ao benefício da retrospectiva, tenha 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. Níveis mais altos tendem a ser criados com mais frequência do que os inferiores.
O EL atual pode ser consultado com a
MRS
instrução: qual é o modo de execução atual / nível de exceção, 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 economizar área de chip. O ARMv8 "Níveis de exceção" diz:
O QEMU, por exemplo, tem como padrão EL1, mas EL2 e EL3 podem ser ativados com opções de linha de comando: qemu-system-aarch64 inserindo el1 ao emular a inicialização do a53
Trechos de código testados no Ubuntu 18.10.
fonte
O espaço do kernel e o espaço do usuário são a separação das funções privilegiadas do sistema operacional e dos aplicativos restritos do usuário. A separação é necessária para impedir que os aplicativos do usuário vasculhem seu computador. Seria ruim se algum programa antigo do usuário pudesse começar a gravar dados aleatórios no disco rígido ou ler a memória do espaço de memória de outro programa do usuário.
Os programas de espaço do usuário não podem acessar os recursos do sistema diretamente, portanto, o acesso é tratado em nome do programa pelo kernel do sistema operacional. Os programas de espaço do usuário geralmente fazem essas solicitações do sistema operacional por meio de chamadas do sistema.
Threads, processos e pilha do kernel não significam a mesma coisa. Eles são construções análogas para o espaço do kernel como suas contrapartes no espaço do usuário.
fonte
Cada processo possui seus próprios 4 GB de memória virtual, que são mapeados para a memória física através de tabelas de páginas. A memória virtual é dividida principalmente em duas partes: 3 GB para o uso do processo e 1 GB para o uso do Kernel. A maioria das variáveis que você cria está na primeira parte do espaço de endereço. Essa parte é chamada de espaço do usuário. A última parte é onde o kernel reside e é comum a todos os processos. Isso é chamado de espaço do kernel e a maior parte desse espaço é mapeada para os locais iniciais da memória física onde a imagem do kernel é carregada no momento da inicialização.
fonte
O tamanho máximo do espaço de endereço depende do tamanho do registro de endereço na CPU.
Em sistemas com registradores de endereço de 32 bits, o tamanho máximo do espaço de endereço é de 2 32 bytes ou 4 GiB. Da mesma forma, em sistemas de 64 bits, 2 64 bytes podem ser endereçados.
Esse espaço de endereço é chamado de memória virtual ou espaço de endereço virtual . Na verdade, não está relacionado ao tamanho físico da RAM.
Nas plataformas Linux, o espaço de endereço virtual é dividido em espaço do kernel e espaço do usuário.
Uma constante específica da arquitetura chamada limite de tamanho da tarefa ou
TASK_SIZE
marca a posição em que a divisão ocorre:o intervalo de endereços de 0 a
TASK_SIZE
-1 é alocado para o espaço do usuário;o restante de
TASK_SIZE
até 2 32 -1 (ou 2 64 -1) é atribuído ao espaço do kernel.Em um sistema específico de 32 bits, por exemplo, 3 GiB podem ser ocupados para espaço do usuário e 1 GiB para espaço do kernel.
Cada aplicativo / programa em um sistema operacional semelhante ao Unix é um processo; cada um deles tem um identificador exclusivo chamado Identificador de processo (ou simplesmente ID do processo , ou seja, PID). O Linux fornece dois mecanismos para criar um processo: 1. a
fork()
chamada do sistema ou 2. aexec()
chamada.Um thread do kernel é um processo leve e também um programa em execução. Um único processo pode consistir em vários encadeamentos que compartilham os mesmos dados e recursos, mas seguem caminhos diferentes pelo código do programa. O Linux fornece uma
clone()
chamada do sistema para gerar threads.Exemplos de usos de threads do kernel são: sincronização de dados da RAM, ajudando o planejador a distribuir processos entre CPUs, etc.
fonte
Resumidamente: o kernel é executado no espaço do kernel, o espaço do kernel tem acesso total a toda a memória e recursos, você pode dizer que a memória é dividida em duas partes, parte do kernel e parte do processo do usuário, (espaço do usuário) executa programas normais, usuário O espaço não pode acessar diretamente o espaço do kernel; portanto, solicita ao kernel que use recursos. por syscall (chamada de sistema predefinida na glibc)
existe uma declaração que simplifica os diferentes " O espaço do usuário é apenas uma carga de teste para o Kernel " ...
Para ser bem claro: a arquitetura do processador permite que a CPU opere em dois modos, Modo Kernel e Modo Usuário , a instrução Hardware permite alternar de um modo para outro.
a memória pode ser marcada como parte do espaço do usuário ou do kernel.
Quando a CPU está executando no Modo de Usuário, a CPU pode acessar apenas a memória que está no espaço do usuário, enquanto a CPU tenta acessar a memória no espaço do Kernel, o resultado é uma "exceção de hardware"; quando a CPU está executando no modo de Kernel, a CPU pode acessar diretamente ao espaço do kernel e ao espaço do usuário ...
fonte
O espaço do kernel significa que um espaço de memória só pode ser tocado pelo kernel. No linux de 32 bits, é 1G (de 0xC0000000 a 0xffffffff como endereço de memória virtual). Todo processo criado pelo kernel também é um thread do kernel, portanto, para um processo, há duas pilhas: uma pilha no espaço do usuário para esse processo e outra no kernel. espaço para thread do kernel.
a pilha do kernel ocupava 2 páginas (8k no linux de 32 bits), inclui um task_struct (cerca de 1k) e a pilha real (cerca de 7k). O último é usado para armazenar algumas variáveis automáticas ou parâmetros de chamada de função ou endereço de função nas funções do kernel. Aqui está o código (Processor.h (linux \ include \ asm-i386)):
__get_free_pages (GFP_KERNEL, 1)) significa alocar memória como 2 ^ 1 = 2 páginas.
Mas a pilha de processos é outra coisa, seu endereço é apenas 0xC0000000 (linux de 32 bits), o tamanho dela pode ser bem maior, usado para as chamadas de função do espaço do usuário.
Então, aqui está uma pergunta para a chamada do sistema, ela está sendo executada no espaço do kernel, mas foi chamada pelo processo no espaço do usuário, como funciona? O linux colocará seus parâmetros e funções na pilha do kernel ou na pilha de processos? Solução do Linux: todas as chamadas do sistema são acionadas pela interrupção do software INT 0x80. Definido na entrada.S (linux \ arch \ i386 \ kernel), aqui estão algumas linhas, por exemplo:
fonte
Por Sunil Yadav, no Quora:
fonte
Espaço curto no kernel é a parte da memória na qual o kernel do linux é executado (espaço virtual superior a 1 GB no caso do linux) e o espaço do usuário é a parte da memória na qual o aplicativo do usuário é executado (os 3 GB inferiores de memória virtual no caso do Linux. quer saber mais veja o link abaixo :)
http://learnlinuxconcepts.blogspot.in/2014/02/kernel-space-and-user-space.html
fonte
Tentando dar uma explicação muito simplificada
A memória virtual é dividida no espaço do kernel e no espaço do usuário. O espaço do kernel é a área da memória virtual onde os processos do kernel serão executados e o espaço do usuário é a área da memória virtual onde os processos do usuário serão executados.
Essa divisão é necessária para proteções de acesso à memória.
Sempre que um carregador de inicialização inicia um kernel após carregá-lo em um local na RAM (normalmente em um controlador baseado em ARM), é necessário garantir que o controlador esteja no modo supervisor com o FIQ e o IRQ desativados.
fonte
Espaço do Kernel e Espaço do Usuário são espaços lógicos.
A maioria dos processadores modernos é projetada para executar em modo privilegiado diferente. As máquinas x86 podem ser executadas em 4 modos privilegiados diferentes.
E uma instrução específica da máquina pode ser executada quando / acima do modo privilegiado específico.
Devido a esse design, você está protegendo o sistema ou aplicando sandbox no ambiente de execução.
Kernel é um pedaço de código, que gerencia seu hardware e fornece abstração do sistema. Portanto, ele precisa ter acesso a todas as instruções da máquina. E é o software mais confiável. Então, eu deveria ser executado com o maior privilégio. E o nível de toque 0 é o modo mais privilegiado. Portanto, o Ring Level 0 também é chamado de Modo Kernel .
Aplicativo do usuário é um software proveniente de qualquer fornecedor de terceiros e você não pode confiar neles completamente. Alguém com intenção maliciosa pode escrever um código para travar seu sistema se ele tiver acesso completo a todas as instruções da máquina. Portanto, o aplicativo deve ter acesso a um conjunto limitado de instruções. E o Nível de toque 3 é o modo menos privilegiado. Portanto, todo o seu aplicativo é executado nesse modo. Portanto, o nível de toque 3 também é chamado de modo de usuário .
Nota: Não estou obtendo os Níveis 1 e 2. do Ring. São basicamente modos com privilégios intermediários. Portanto, pode ser que o código do driver do dispositivo seja executado com esse privilégio. AFAIK, linux usa apenas Ring Level 0 e 3 para execução de código do kernel e aplicativo do usuário, respectivamente.
Portanto, qualquer operação acontecendo no modo kernel pode ser considerada como espaço no kernel. E qualquer operação acontecendo no modo de usuário pode ser considerada como espaço do usuário.
fonte
A resposta correta é: Não existe espaço no kernel e espaço do usuário. O conjunto de instruções do processador possui permissões especiais para definir itens destrutivos, como a raiz do mapa da tabela de páginas, ou acessar a memória do dispositivo de hardware, etc.
O código do kernel possui os privilégios de nível mais alto e o código de usuário, o mais baixo. Isso evita que o código do usuário trate o sistema, modifique outros programas etc.
Geralmente, o código do kernel é mantido em um mapa de memória diferente do código do usuário (assim como os espaços do usuário são mantidos em mapas de memória diferentes um do outro). É daí que vêm os termos "espaço do kernel" e "espaço do usuário". Mas essa não é uma regra rígida e rápida. Por exemplo, como o x86 exige indiretamente que seus manipuladores de interrupção / interceptação sejam mapeados o tempo todo, parte (ou alguns SOs todos) do kernel deve ser mapeada no espaço do usuário. Novamente, isso não significa que esse código tenha privilégios de usuário.
Por que a divisão kernel / usuário é necessária? Alguns designers discordam que é, de fato, necessário. A arquitetura do microkernel é baseada na idéia de que as seções de código com maior privilégio devem ser as menores possíveis, com todas as operações significativas realizadas no código com privilégios de usuário. Você precisaria estudar por que essa pode ser uma boa idéia, não é um conceito simples (e é famoso por ter vantagens e desvantagens).
fonte
O get de memória é dividido em duas áreas distintas:
Os processos em execução no espaço do usuário têm acesso apenas a uma parte limitada da memória, enquanto o kernel tem acesso a toda a memória. Os processos em execução no espaço do usuário também não têm acesso ao espaço do kernel. Os processos de espaço do usuário podem acessar apenas uma pequena parte do kernel por meio de uma interface exposta pelo kernel - o sistema chama.Se um processo executar uma chamada do sistema, uma interrupção do software é enviada ao kernel, que então despacha o manipulador de interrupção apropriado e continua seu trabalho após a conclusão do manipulador.
fonte
No Linux, existem dois espaços: o 1º é o espaço do usuário e o outro é o espaço kernal. O espaço do usuário consiste apenas no aplicativo do usuário que você deseja executar. como serviço kernal, há gerenciamento de processos, gerenciamento de arquivos, manipulação de sinais, gerenciamento de memória, gerenciamento de encadeamentos e muitos serviços estão presentes lá. se você executar o aplicativo no espaço do usuário em que o aplicativo interage apenas com o serviço kernal. e esse serviço é interagir com o driver de dispositivo presente entre o hardware e o kernal. o principal benefício do espaço kernal e da separação do espaço do usuário é que podemos obter uma segurança pelo virus.bcaz de todos os aplicativos de usuário presentes no espaço do usuário e o serviço está presente no espaço kernal. é por isso que o linux não afeta o vírus.
fonte