Pesquisar este blog

Novidades no blog

- Passamos das 120k visitas \o/

- Os repositórios ainda precisam ser organizados!

- Nova postagem: Organizando a casa;
- LOS versão 0.7 (acesse, em breve, no github.com);

segunda-feira, 15 de abril de 2013

Boot, fase 4 - Entrando no Modo Protegido

O próximo passo é executar o kernel no Modo Protegido, mas para isso é necessário que o procedimento de chamada do kernel seja melhorado. Ele precisa habilitar o Modo Protegido, configurar todos os registradores de segmento e a pilha, e saltar para o kernel.

Mas antes de realmente partir para o Modo Protegido, implementei o procedimento de chamada do kernel ainda no Modo Real por ser mais fácil de testá-lo.

Uma dificuldade foi idealizar um modo de atualizar todos os registradores e segmentos, porque os parâmetros estão na pilha, se ela for alterada não será possível acessar o demais parâmetros. Os registradores da CPU não são em número suficiente para armazenar todos os parâmetros. Então cheguei ao seguinte algorítimo:

Ele primeiro copia os parâmetros CS, DS, ES, o Ponto de Entrada e o Parâmetro do kernel para variáveis no segmento de dados atual. Sobrando SS e o Ponteiro de Pilha.

Então ele pega SS e o Ponteiro de Pilha e os coloca em registradores da CPU (AX/DX), configura o novo SS e, então, SP e BP. Pronto, a nova pilha está configurada.

Agora falta os outros registradores de segmento e executar o salto. Para isso, primeiro ele pega o endereço do salto e coloca na pilha (a nova), de forma que uma instrução RETF possa saltar para o kernel.

Encima do endereço do salto ele coloca o valor de DS e ES e pega o valor do Parâmetros do kernel em AX. Então ele retira DS e ES da pilha diretamente para os registradores corretos (POPs).

Agora todos os segmentos (exceto CS) estão corretos, a pilha está configurada e o Parâmetros do kernel está em AX, basta somente usar um RETF e CS:IP será atualizado fazendo o salto para o kernel.


Depois de uma versão funcional, adicionei uma GDT com 5 entradas:
  • 0x00 = Entrada nula (obrigatória na GDT);
  • 0x08 = Segmento de código (onde o kernel foi carregado);
  • 0x10 = Segmento de dados (o mesmo utilizado pelo bootloader);
  • 0x18 = Segmento de pilha (o mesmo utilizado pelo bootloader);
  • 0x20 = Segmento de vídeo (aponta para o semento de vídeo);

Agora o procedimento de chamada do kernel também comuta o processador para o Modo Protegido, imediatamente depois de copiar os parâmetros para o segmento de dados e antes de configurar a nova pilha.

Os parâmetros do ambiente de execução são exibidos e o kernel é chamado. O kernel agora está rodando no Modo Protegido de 16 bits, mas ainda na memória convencional.


Depois de ter o kernel rodando no Modo Protegido revisei os códigos e criei uma outra versão mais organizada.


Download dos fontes e binários:

Nenhum comentário:

Postar um comentário

Obs.: Após escrever seu comentário, inscreva-se por e-mail para seguir os próximos comentários. Ou assine a postagem de comentários (Atom).