Considere que o curso normal de ação do SO quando ele encontra essa classe de erros é encerrar o processo ofensivo.
O problema é, o que você faz se o erro ocorrer dentro do limite do kernel? Você não pode simplesmente matar o kernel, porque, mesmo que seja possível, isso iria travar o sistema imediatamente, deixando o sistema operacional sem uma maneira de relatar o que deu errado, reinicialize (na ausência de, por exemplo, um watchdog do kernel independente do kernel), armazenando dados de diagnóstico ou qualquer outra coisa que possa ser considerada útil em caso de falha do sistema operacional. p>
Assim, o sistema operacional faz o segundo melhor: ele exibe e possivelmente armazena as informações de diagnóstico primeiro e depois entra em algum estado no qual o controle nunca passa de uma parte específica do kernel. Com efeito, o sistema é então congelado, porque nada mais será executado antes que o sistema seja reinicializado. O kernel pode executar algo como uma HLT
instrução , inserir um loop infinito, desabilitar interrupções de entrada, acionar uma reinicialização do sistema, ou faça o que for mais apropriado.
Dependendo do sistema operacional, coisas diferentes podem acionar falhas do kernel. Um exemplo possível é uma falha de página durante a execução com interrupções desativadas; outra é uma chamada do kernel que falha nas pré-condições ou nas verificações de integridade (é isso que IRQL_NOT_LESS_OR_EQUAL
é tudo sobre, por exemplo). Para obter uma lista de coisas que podem acionar BSODs no Windows, consulte, por exemplo, esta lista códigos de erro STOP no Windows 2000 no MSDN.
Nesse contexto, também é importante considerar as diferenças entre o que é executado dentro do limite do kernel e, portanto, tem o potencial de causar uma falha fatal no sistema, em vez de simplesmente travar um único processo. Qualquer coisa que esteja sendo executada fora do kernel (ou, mais precisamente, na Intel, fora do anel 0) pode ser restringida pelo kernel, e esta é uma grande razão pela qual, por exemplo, proteção e troca de memória entre processos é possível ou prática (cada processo é configurado de tal forma que ele pode acessar apenas sua própria memória, imposta pela CPU, e qualquer violação causa uma falha de página que é manipulada pelo kernel e pode resultar na página solicitada ser recarregada a partir da troca, ou o kernel lançando um erro de proteção de memória e encerrando o processo problemático). Em um sistema operacional de kernel monolítico, muitas coisas rodam dentro do limite do kernel - isso é feito frequentemente para melhorar o desempenho, já que os switches de contexto dentro e fora do kernel são particularmente caros, mas sobrecarrega os programadores de drivers up, como qualquer erro (em um momento inoportuno, ou sempre, dependendo da classe de erro) ao executar no modo kernel é crítico ao sistema. Em um SO de microkernel, em contraste, apenas o mínimo de código é executado no anel 0 (ou equivalente) - geralmente, isso é limitado a coisas como gerenciamento de memória, agendamento de processos e algumas outras coisas que requerem esse nível de acesso ao sistema completo - e o restante é executado no modo de usuário e se comunica com o kernel por meio de uma interface bem definida. Fazer isso permite que os mesmos controles de acesso usados nos processos de usuário também protejam o código relacionado ao kernel e com uma interface adequadamente definida (por exemplo, qualquer driver deve ser capaz de reinicializar o hardware correspondente no carregamento de um sistema em execução, mesmo se o driver tiver sido carregado antes e o dispositivo de hardware estiver em um estado potencialmente desconhecido), isso pode funcionar. A desvantagem é que todos aqueles contextos que entram e saem do kernel degradam o desempenho do sistema, e que foi alegadamente uma grande razão para o Windows NT 4.0 (comparado ao NT 3.x), a Microsoft mover drivers de dispositivos para executar no ring 0 do que o anel 3.