Primeiro, precisamos ver o que acontece no nível do hardware. Uma falha de página acontece quando a MMU tenta excluir a referência de um endereço virtual e encontra um descritor inválido para esse endereço. Quando isso acontece, o processador executa um trap: ele alterna para o modo kernel, pula para um endereço predefinido (o vetor trap) e preenche alguns registradores para indicar que uma falha de página aconteceu, e informações suficientes para permitir que o kernel determine o que endereço solicitado foi, quais instruções causaram a falha e em qual tarefa. Eu estou dando a idéia geral aqui, os detalhes concretos variam entre arquiteturas de processador.
O código do manipulador de trap, que faz parte do kernel, examina registros e memória para determinar a natureza da falha (o mesmo manipulador pode ser chamado para diferentes tipos de exceções), o endereço solicitado e qual processo que estava ativo anteriormente . Em seguida, ele consulta algumas estruturas de dados que indicam o que deve ser mapeado nesse processo nesse endereço. Aqui, novamente, a natureza da estrutura de dados varia entre as arquiteturas do processador e também entre as variantes do Unix. Algumas arquiteturas de processador têm bits suficientes em um descritor inválido que não são interpretados pela MMU para armazenar um número de setor de swap, caso em que o kernel não precisa consultar nenhuma outra estrutura de dados. Se esse não for o caso, o kernel consultará uma estrutura de dados anexada ao processo e descreverá seus mapeamentos de memória.
O mesmo mecanismo também pode determinar várias outras coisas, como:
- A página precisa ser carregada de um arquivo, para arquivos mapeados pela memória.
- A memória é mapeada, mas a operação não foi autorizada, por ex. Foi uma tentativa de escrever para a memória somente leitura. Neste caso, o kernel organiza a troca de controle para o sinal SIGSEGV do processo, se houver um, e caso contrário, o processo é finalizado.
- Foi feita uma tentativa de gravar em uma página marcada como somente leitura para a CPU, mas marcada como copy-on-write. Nesse caso, o kernel faz uma cópia da página.
Se o kernel conseguir obter uma página na RAM que tenha o conteúdo que o processo espera, atualizará o mapa de memória do processo para refletir isso. Então o kernel transfere o controle de volta ao processo, como em um switch de contexto; mas em vez de retornar o controle logo após a instrução de que o processo foi executado, ele retorna o controle imediatamente antes desta instrução, de modo que a instrução com falha seja executada novamente, desta vez com sucesso.