A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Oficina

7. O primeiro loader

Sab

26

Mai

2007


15:16

(10 votos, média 4.20 de 5) 


Nível avançado MÓDULO 7 do SO Numaboa

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 :thumbdown:

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 tongue ), 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).

Informações adicionais