MÓDULO 7 - O primeiro loader

Até que enfim! Depois de ver um montão de teoria nos módulos anteriores podemos começar a por a mão na massa. É claro que usaremos disquete porque, como principiantes que somos, periga detonarmos o HD

As informações contidas neste tutorial podem ser consideradas PERIGOSAS. Aviso que, se algo desastroso ocorrer com a sua máquina, não vou poder ser responsabilizada. As informações e orientações do texto estão corretas e os programas foram exaustivamente testados antes de serem publicados. Como os erros de programação são comuns, ocorrendo mesmo com programadores profissionais (veja o pessoal da Microsoft ), quero que todos fiquem cientes de que não posso ser penalizada por eventuais erros cometidos pelos usuários.

O perigo não é tamanho para que possa fazer com que todos desistam deste tutorial. O aviso é uma formalidade que comumente acompanha textos de risco. É só isso. Então vamos lá, pessoal, mãos à obra!

O carregador de boot

O carregador de boot, ou boot loader, nada mais é do que o conteúdo do setor de boot. Como já sabemos, precisa estar localizado no cilindro 0, cabeça 0, setor 1 de um disquete. Sabemos também que um setor de disquete possui 512 bytes, portanto, nosso boot loader também precisa ter 512 bytes. Para identificar um setor como sendo de boot, é preciso que ele tenha uma assinatura para que a BIOS o reconheça como tal - são os dois últimos bytes e que contém 55 AA (ou 85 e 170 na notação decimal).

Sabemos também que, depois que o setor de boot for lido, seu conteúdo é transferido para o endereço de memória 0000:7C00. Vamos precisar desta referência quando escrevermos nosso boot loader em Assembly. E, falando em Assembly, vamos usar o NASM.

Um esqueleto de carregador

O exemplo abaixo NÃO é para ser utilizado como boot loader. É apenas um esqueleto que servirá de base para criar um carregador melhorzinho.

; Para começar
[BITS 16]       ; Informa o compilador para gerar código de 16 bits
 
[ORG 0x7C00]    ; Origem, informa o compilador onde o código deverá estar
                ; localizado na memória depois de ser carregado
 
; Para terminar
times 510-($-$$) db 0   ; Preenche o resto do setor com zeros
db 0x55,0xAA            ; Põe a assinatura do boot loader no final

Você deve estar se perguntando porque 16 bits. Depois de muito tempo com processadores de 32 bits e atualmente na era dos 64 bits, um loader de 16 bits parece brincadeira. Acontece que estamos começando e, neste caso, nada melhor do que seguir a evolução que os processadores também seguiram. Além disso, o DOS não está morto e enterrado, e, que me conste, ainda trabalha em 16 bits.

As linhas de comentário, iniciadas por ponto e vírgula, explicam o que este esqueleto representa. Duas linhas merecem uma explicação melhor: times é uma diretiva que só o NASM entende. Faz com que sejam inseridos tantos zeros quanto forem necessários até o arquivo atingir o tamanho de 510 bytes ($ significa início da instrução e $$ significa início do programa).

Um carregador com loop infinito

Se criarmos um loop infinito, o que será que acontece? Vamos pagar para ver. Abra seu editor de texto (eu uso o silicioPad, o bloco de notas do windows que modifiquei para que mostre o número das linhas e que está disponível na seção de downloads - Informática / Editores) e digite o código abaixo:

[BITS 16]  ; Código de 16 bits
[ORG 0x7C00]  ; Origem do código em 7C00
 
principal:  ; Marcador de início
jmp $    ; Saltar para o início desta instrução (o loop infinito)
    ; Uma outra alternativa seria jmp principal que
    ; também funcionará como loop infinito
 
; Para terminar
times 510-($-$$) db 0  ; Preenche o resto do setor com zeros
db 0x55,0xAA    ; Põe a assinatura do boot loader no final

Salve o código fonte (por exemplo, como loader1.asm) num diretório de trabalho. Ponha uma cópia do NASM no mesmo diretório, só para facilitar as coisas. A seguir, compile o loader1.asm com o comando de linha nasm -f bin loader1.asm -o loader1.bin para obter um arquivo em binário puro. A chave -f (de file) indica o tipo de arquivo compilado (no caso, -f bin) e a chave -o (de output) indica o nome que o arquivo compilado deve receber (no caso, loader1.bin).

Se você tiver a curiosidade de abrir o arquivo loader1.bin num editor hexadecimal, vai encontrar 508 bytes zerados precedidos por EB FE e seguidos por 55 AA, totalizando 512 bytes. Nosso setor de boot está pronto para ser transferido para um disquete.

Transferindo o loader1.bin para o setor de boot

Normalmente não se tem acesso ao setor de boot de um disquete. Este setor é preparado pelo programa format.exe quando o formatamos. Depois disto só é possível visualizá-lo e/ou alterá-lo através de métodos específicos. Como estamos engatinhando, vamos usar os meios mais básicos.

Antes de mais nada, formate um disquete para que sirva de teste. Verifique sua integridade e confira o setor de boot.

A primeira forma básica de alterar um setor de boot é fazer uma escrita direta através de um editor hexadecimal que possa acessar o setor de boot. Este é um dos motivos que tenho para usar o WinHex. Se você optar por esta solução, vai ter um pouco de trabalho: altere cada byte do setor, ou seja, comece com EB FE, depois preencha os 508 bytes seguintes com zeros e termine com 55 AA. Salve as alterações.

A segunda forma é utilizando o programa debug.exe do Windows, um procedimento bastante simples. Faça uma cópia do binário loader1.bin e do executável debug.exe para o disquete (o debug.exe está no diretório system32 do Windows). Passe para o drive A: (ou onde estiver seu disquete) e chame debug.exe loader1.bin para abrir uma janela do DOS, cujo cursor é - (um traço). Digite w 100 0 0 1, o que força a escrita (write) para o endereço 100, drive 0, primeiro setor 0 e número 1.

Se você estiver operando com Linux, insira um disquete no drive mas não o monte. Depois acione o dd com dd if=loader1.bin bs=512 of=/dev/fd0.

Tendo transferido o loader1.bin para o setor de boot, o disquete não é mais reconhecido pelo Windows (ou pelo Linux). Se quisermos dar uma olhada no setor de boot vai ser preciso um programa diferente dos editores hexadecimais tradicionais (como o WinHex).

Testando o bootloader

Nosso disquete de boot está pronto. Verifique se a BIOS da sua máquina está configurada para seguir a sequência de boot de drive A:, C:, etc, ou seja, para que procure inicialmente no drive de disquete um setor de boot.

Pronto! Dê um reset na sua máquina ou digite Ctrl+Alt+Del. Ao verificar o primeiro setor do disquete, ela encontra a assinatura 55 AA. Portanto, vai executar o código EB FE e entrar num loop infinito. Moral da história: você acaba de "bootar" a máquina com um sistema operacional que... NÃO FAZ NADA! E é exatamente isto que pretendíamos, um loop infinito que não faz nada

Considerações finais

Se tudo funcionou como o previsto, parabéns! Aliás, voltando ao tema texto perigoso: não foi tão perigoso assim. O máximo que poderia acontecer seria o aparecimento de uma porção de mensagens de erro na hora da leitura do setor de boot do disquete. Caso isto ocorra, tire o disquete do drive e reiniciar a máquina

Quero agradecer ao Daniel Rowell Faulkner, estudante inglês cujo interesse principal parece ser a linguagem Python, pelo excelente texto "Hello World Boot Loader", que serviu como uma das fontes para este módulo. Infelizmente seu site saiu do ar.

 

 

Free Web Hosting