Conforme vamos implementando uma coisa ou outra surgem pequenos detalhes que inicialmente nem percebemos, mas que podem se tornar um grande impedimento no futuro. E esse futuro já seria o próximo passo, a implementação dos gerenciadores de memória. Para sanear isso implementei uma nova versão antes...
O primeiro problema a resolver é justamente o do linker não criar a sessão BSS na imagem do kernel, se bem que isso na verdade não é um problema (é uma vantagem, já que a imagem fica menor). O problema em si é que o bootloader não sabe sobre a sessão BSS e então não atribui corretamente o espaço de memória à imagem do kernel, remontando a sessão BSS e o Heap (ou a Pilha, dependendo da configuração do kernel).
A maneira com a qual resolvi esse problema foi utilizando os símbolos criados pelo linker, que como pensava são globais, ou seja, podem ser acessados em qualquer parte do código, tanto em Pascal quanto em Assembly. Depois de alguns testes conclui também que é possível utilizar símbolos diretamente na nossa tabela de kernel.
A tabela de kernel, foi remodelada e agora funciona de modo diferente, ela deixou de ser simplesmente uma tabela que poderia ser "ignorada" passando a ser um cabeçalho de arquivo. Agora não há mais o jmp inicial e a tabela, obrigatoriamente, tem que ser lida para encontrar o ponto de entrada do código.
O cabeçalho do arquivo do kernel começa no primeiro byte do arquivo, possui uma assinatura e alguns campos fixos, que determinam o seu "tipo", o que possibilita que diversos formatos de arquivos sejam criados com um cabeçalho padrão do sistema.
Alguns campos foram adicionados na nova tabela, entre eles a Arquitetura, Início e Fim da imagem, Ponto de Entrada, Início das sessões: Code, Data e BSS.
Os campos de endereços são atribuídos durante a montagem do código Assembly e são automaticamente realocados pelo linker utilizando símbolos criados durante a linkedição. Dessa forma não é necessário se preocupar com o tamanho final da imagem a cada recompilação, pois tudo é feito de automaticamente.
Devido a essa mudança realizada no arquivo de kernel, o bootloader na versão 0.14 não é mais capaz de carregar o kernel e portanto foi necessário uma nova versão dele. Como já havia notado que algumas informações úteis ficaram de fora dos parâmetros, que são passados ao kernel, resolvi implementar algumas mudanças nesses parâmetros nesta nova versão do bootloader, desta forma já resolvi dois problema de uma só vez.
O segundo problema é que a única informação sobre a memória inferior que tinhamos era a sua quantidade. Isso nem seria um problema se o boot tivesse ocorrido diretamente pela BIOS, mas como ainda utilizamos um boot-parasita e teremos que utilizar o modo real, para as chamadas de BIOS, não podemos simplesmente sobrescrever o que estiver na memória inferior.
Abaixo os snapshots da nova versão do bootloader (no modo de depuração), observe os dados coletados do arquivo de kernel e os parâmetros passado a ele:
Não tirei um snapshot no modo normal, pois como o kernel ocupa toda a tela nada aparecerá alem das informações impressas pelo kernel, como segue abaixo:
Bem, esse foi o resultado de uma passadinha rápida por aqui, agora acho que a próxima só em novembro mesmo.. ;)
Edit: Após organizar os repositórios no github, modifiquei a funcionalidade dos pacotes (seguindo os repositórios), assim o pacote "kernel" tem somente o kernel do SO, e o pacote "system" possui agora todas as partes necessárias para funcionamento do sistema (ex.: kernel, bootloader, shell, ...).
Download dos fontes e binários:
Próximo - Kernel, fase 5 - Adornando o caminho >>
<< Anterior - Kernel, fase 3 - Construindo alicerces
Voltar a Faça seu próprio sistema operacional.
O primeiro problema a resolver é justamente o do linker não criar a sessão BSS na imagem do kernel, se bem que isso na verdade não é um problema (é uma vantagem, já que a imagem fica menor). O problema em si é que o bootloader não sabe sobre a sessão BSS e então não atribui corretamente o espaço de memória à imagem do kernel, remontando a sessão BSS e o Heap (ou a Pilha, dependendo da configuração do kernel).
A maneira com a qual resolvi esse problema foi utilizando os símbolos criados pelo linker, que como pensava são globais, ou seja, podem ser acessados em qualquer parte do código, tanto em Pascal quanto em Assembly. Depois de alguns testes conclui também que é possível utilizar símbolos diretamente na nossa tabela de kernel.
A tabela de kernel, foi remodelada e agora funciona de modo diferente, ela deixou de ser simplesmente uma tabela que poderia ser "ignorada" passando a ser um cabeçalho de arquivo. Agora não há mais o jmp inicial e a tabela, obrigatoriamente, tem que ser lida para encontrar o ponto de entrada do código.
O cabeçalho do arquivo do kernel começa no primeiro byte do arquivo, possui uma assinatura e alguns campos fixos, que determinam o seu "tipo", o que possibilita que diversos formatos de arquivos sejam criados com um cabeçalho padrão do sistema.
Alguns campos foram adicionados na nova tabela, entre eles a Arquitetura, Início e Fim da imagem, Ponto de Entrada, Início das sessões: Code, Data e BSS.
Os campos de endereços são atribuídos durante a montagem do código Assembly e são automaticamente realocados pelo linker utilizando símbolos criados durante a linkedição. Dessa forma não é necessário se preocupar com o tamanho final da imagem a cada recompilação, pois tudo é feito de automaticamente.
Devido a essa mudança realizada no arquivo de kernel, o bootloader na versão 0.14 não é mais capaz de carregar o kernel e portanto foi necessário uma nova versão dele. Como já havia notado que algumas informações úteis ficaram de fora dos parâmetros, que são passados ao kernel, resolvi implementar algumas mudanças nesses parâmetros nesta nova versão do bootloader, desta forma já resolvi dois problema de uma só vez.
O segundo problema é que a única informação sobre a memória inferior que tinhamos era a sua quantidade. Isso nem seria um problema se o boot tivesse ocorrido diretamente pela BIOS, mas como ainda utilizamos um boot-parasita e teremos que utilizar o modo real, para as chamadas de BIOS, não podemos simplesmente sobrescrever o que estiver na memória inferior.
Abaixo os snapshots da nova versão do bootloader (no modo de depuração), observe os dados coletados do arquivo de kernel e os parâmetros passado a ele:
Não tirei um snapshot no modo normal, pois como o kernel ocupa toda a tela nada aparecerá alem das informações impressas pelo kernel, como segue abaixo:
Bem, esse foi o resultado de uma passadinha rápida por aqui, agora acho que a próxima só em novembro mesmo.. ;)
Edit: Após organizar os repositórios no github, modifiquei a funcionalidade dos pacotes (seguindo os repositórios), assim o pacote "kernel" tem somente o kernel do SO, e o pacote "system" possui agora todas as partes necessárias para funcionamento do sistema (ex.: kernel, bootloader, shell, ...).
Download dos fontes e binários:
- LoadLOS.015 (necessário para carregar o novo kernel);
- Kernel.005;
Próximo - Kernel, fase 5 - Adornando o caminho >>
<< Anterior - Kernel, fase 3 - Construindo alicerces
Voltar a Faça seu próprio sistema operacional.
Parabéns por todos os passos. Abraço
ResponderExcluirCaro Luiz, ainda há muitos passos a serem dados até que o LOS seja um sistema realmente operacional, mas como ele não é a maior prioridade da vida está recebendo pouco do meu tempo...
ExcluirEspero em breve dar continuidade ao projeto.