Sítio do Piropo

B. Piropo

< Coluna em Fórum PCs >
Volte
15/10/2007

< Computadores XLIV: >
<
Inicializando o DOS >


Bem, agora que destrinchamos o velho PC e sabemos o que é a memória principal e onde ela se localiza, podemos afinal decifrar o intrigante mistério do “boot”, ou seja, como o computador consegue, sem qualquer ajuda externa, carregar na memória o sistema operacional e se apresentar pronto para uso após ser ligado, dando a impressão de executar a façanha atribuída ao nobilíssimo Barão de Münchausen: elevar-se acima do solo puxando para cima os cordões (“bootstraps”) das próprias botinas (“boots”).

O aparente paradoxo da inicialização do PC advém do fato de que o sistema operacional (SO) é um programa e programas só podem ser carregados na memória por outro programa cujas instruções devem obrigatoriamente estar presentes na memória principal. Por outro lado, pelo menos em tese, a MP deveria estar “vazia” ao se ligar o micro já que ela se constitui essencialmente de “chips” de memória volátil (do tipo RAM) cujo conteúdo é perdido ao se desligar o micro. Então como é possível que lá houvesse instruções para carregar o sistema operacional assim que o micro é ligado?

Como os mais espertos dentre vocês já perceberam (ou seja, todos, já que meus leitores são sempre os mais espertos...), o mistério desaparece quando se lê novamente o parágrafo anterior e se dá atenção ao advérbio “essencialmente” e à locução “em tese”. Pois, como vimos nas colunas anteriores, nem toda a memória principal é constituída de “chips” de memória volátil. Alguns trechos do espaço de endereçamento são preenchidos por posições de memória que se situam em “chips” de memória não volátil (mais exatamente, no tempo do PC, memória permanente do tipo ROM) que são capazes de preservar seu conteúdo mesmo quando não alimentados por corrente elétrica, ou seja, quando o micro está desligado.

Logo, para que o sistema operacional seja carregado na memória ao se ligar o micro, tudo o que se faz necessário é armazenar as rotinas responsáveis por este suposto milagre em chips de memória não volátil e “apontar” o ponteiro de instruções (PI) para o endereço inicial destas rotinas (se não entendeu a razão disso, sugiro a releitura atenta da coluna “Computadores XX: Busca e execução – Primeiro passo” e da subseqüente). Portanto, mistério mesmo não há. Como, aliás, não há mistério em nada que se relacione com informática, computadores, sua arquitetura e funcionamento. Tudo é na verdade muito simples e quem afirmar o contrário está apenas tentando valorizar o conhecimento (geralmente escasso) que detém sobre o assunto.

Não obstante, o procedimento de inicialização, mesmo não implicando qualquer mistério, vai tão além de simplesmente carregar o sistema operacional na memória que definitivamente merece consideração. Então vamos dedicar alguma atenção a ele, mesmo que de forma superficial (se você deseja informações mais detalhadas sobre cada passo do procedimento de inicialização do PC, incluindo a possibilidade de efetuar inicializações com diferentes sistemas operacionais via “boots” múltiplos e gerenciamento do “boot”, pode obtê-las na série de colunas “Microcosmos”, que assinei em O Globo de dezembro de 1994 a novembro de 1996; toda a série permanece disponível na seção < http://www.bpiropo.com.br/escritos.htm > “Escritos / Microcosmo” do < http://www.bpiropo.com.br/ > “Sítio do Piropo” e as colunas referentes ao procedimento de inicialização do PC foram publicadas entre 20/11/1995 e 04/03/1996).

Evidentemente, da mesma forma que os sistemas operacionais para a linha PC evoluíram versão após versão desde o velho DOS até sistemas modernos como Vista e Linux, também o procedimento de inicialização sofreu evolução equivalente. Mas a estrutura básica manteve-se essencialmente a mesma, inclusive iniciando-se com os modernos processadores operando no “modo Real”, um modo de operação que emula o do velho Intel 8086, o processador do XT. E como o que nos interessa é tão somente entender a forma pela qual a máquina, ao ser ligada, sai de seu estado de letargia e apresenta-se pronta para o uso sem qualquer contribuição do usuário exceto o apertar de um botão, vamos nos ater apenas ao procedimento de inicialização de um micro que será gerenciado por um sistema operacional simples, como o DOS.

Figura 1: O velho DOS nas versões MS e IBM.

Inicializando o DOS

Para que o procedimento de inicialização seja possível, é necessário cumprir duas condições: as rotinas responsáveis por ele devem estar gravadas em um chip de memória não volátil e o ponteiro de instruções deve “apontar” para o início da primeira rotina a ser executada.

No caso do DOS, as rotinas de inicialização vinham gravadas em um chip de memória não volátil (inicialmente ROM, depois PROM, EPROM, EEPROM e, finalmente, Flash; mais sobre estes tipos de CIs nas colunas seguintes), conhecido como “ROM BIOS” que, como vimos na coluna anterior, ocupava os últimos 16 KB do espaço de endereçamento.

Curiosamente o endereço inicial da primeira rotina a ser executada para inicializar a máquina era FFFF0h (ou 1.048.560 em decimal), quase no final do espaço de endereçamento do PC (que corresponde a 1 MB, endereço FFFFFh ou 1.08.575 em decimal). Para ser exato, meras 16 posições de memória (16 bytes) abaixo do limite superior.

Portanto, imediatamente após o microprocessador ser energizado, seu registrador denominado “Ponteiro de Instruções” (PI) deveria conter exatamente aquele endereço. E para que isso ocorresse era necessário que ele viesse assim “de fábrica”. E de fato assim era: logo que um 8086 era “ligado” seus dois registradores internos que, juntos, constituíam o PI, continham o endereço FFFF0h (o velho PC usava um sistema de endereçamento conhecido por “segmento e deslocamento” nos quais todo endereço – de vinte bits – precisava de dois registradores – de dezesseis bits – para ser armazenado).

Isso ocorria porque o microprocessador era fabricado assim e não dependia de nenhuma intervenção de quem quer que seja. Portanto, ligada a máquina, seu primeiro “ciclo de busca e execução” ia buscar no endereço FFFF0h da memória principal a primeira instrução a ser executada. E a partir deste momento a UCP nada mais fazia senão a única coisa que, como sabemos, ela é capaz de fazer sozinha: executar ciclos sucessivos de busca e execução até ser desligada.

Ora, uma rotina que se situa a apenas 16 bytes do final do espaço de endereçamento não poderia fazer muita coisa. E, de fato, não fazia. Continha apenas uma instrução “jump”, que fazia o PI saltar para outro endereço, também situado no interior do trecho ocupado pelo chip “ROM BIOS” onde, aí sim, iniciava-se a rotina responsável pelos primeiros passos do procedimento de inicialização.

Estes primeiros passos disparavam o “auto-teste de partida” (ou POST, de “Power On Self Test”), uma sucessão de rotinas que testam, um a um, todos os componentes que fazem parte do (ou estão conectados ao) computador e que interrompiam a inicialização com uma mensagem de erro caso dessem por falta de algum dispositivo ou constatassem que estava funcionando mal. No decurso do POST acendiam-se os LEDs do teclado, do disco rígido, dos acionadores de disco flexível e dos demais componentes à medida que eram testados e apareciam na tela mensagens indicando o tipo do processador, a capacidade de memória instalada, tipo de controlador de vídeo e coisas que tais.

Terminado o POST, inicia-se uma nova série de rotinas, ainda armazenadas no “ROM BIOS”, que copiam na memória RAM algumas informações (sob a forma de tabelas; mais precisamente os chamados “vetores de interrupção”, para quem gosta de detalhes) que serão posteriormente usadas pelo sistema operacional e em seguida vasculham todo o espaço de endereçamento em busca de outros chips de memória não volátil (como os que contêm as rotinas de controle de periféricos presentes nos controladores de vídeo e acionadores de disquete que vimos na < t=221949" target="_blank">http://www.forumpcs.com.br/viewtopic.php?t=221949 >coluna anterior) e quando as encontra anota seus trechos de endereços em uma tabela das “extensões de BIOS” que posteriormente será consultada pelo sistema operacional (SO) quando carregado.

Se você leu com atenção os parágrafos anteriores deve ter notado que até o momento o SO permanece intocado no disco rígido, disquete, fita ou seja lá onde seus arquivos estiverem armazenados. Tudo o que se fez foi testar o hardware e copiar algumas tabelas no trecho inicial da memória RAM. A tentativa de carregar o sistema operacional (“tentativa” porque até então ninguém pode garantir que sequer exista um SO nas imediações) começa exatamente neste ponto.

Atualmente se pode decidir onde procurar primeiro ajustando convenientemente o “setup”. No tempo do PC a ordem de busca era imutável: começava pelo acionador de disquete, verificando se havia um instalado, se em seu interior havia um disquete e, em havendo, lia seu “setor de boot” para verificar se este disquete era um “disco de sistema”, ou seja, que continha os arquivos do SO (um pouco mais tarde, com o advento do XT e do suporte a discos rígidos, essa busca se estendeu a estes dispositivos).

Se não encontrava nenhum disco de sistema, o procedimento de inicialização partia do pressuposto que aquele era um PC sem discos e tentava passar o controle para o BASIC residente, apontando o PI para o endereço de inicialização do BASIC situado nos chips de memória ROM que continham esta linguagem de programação (veja < t=221949" target="_blank">http://www.forumpcs.com.br/viewtopic.php?t=221949 > coluna anterior). Mas nem todo o PC continha estes chips (os que podiam usar o “prompt” do próprio BASIC para comandar a carga de um SO armazenado em fita cassete).

Se não houvesse um disco de sistema e não fosse encontrado um BASIC residente, não havia como dar partida na máquina. Neste caso procedimento de inicialização era interrompido e aparecia na tela uma mensagem de erro indicando que naquele sistema não foram encontrados os chips de memória ROM responsáveis pela inicialização e carga do ROM BASIC.

Neste ponto cabe um comentário quase folclórico. Pois acontece que toda mensagem exibida durante o procedimento de inicialização tinha, necessariamente, que estar gravada nos chips do “ROM BASIC”. E, portanto, tinham que se espremer em seus escassos 16 KB juntamente com todas as rotinas. Não é, portanto, de se admirar que estas mensagens fossem extremamente concisas (da primeira vez que me deparei um “erro fatal” cogitei, aflito, quem ou o que teria eu inadvertidamente matado). A mensagem que indicava a falta da linguagem BASIC rezava apenas: “NO ROM BASIC”, assim mesmo, toda em maiúsculas. Alguns anos depois, já na era do AT e 386, as máquinas já não vinham com a linguagem BASIC gravada em ROM e na verdade pouca gente sabia que um dia existiram máquinas assim. Mas a mensagem continuou lá, nas entranhas do DOS (que, não esqueçam, era carregado na inicialização de todas as versões de Windows até Win 98). E aparecia sempre que falhavam todas as tentativas de carregar o sistema operacional. Jamais me esquecerei do olhar de espanto de um usuário quando o “ténico” que ele havia chamado para reparar sua máquina se deparou com aquela mensagem e, tentando manter a pose, declarou com ar de profundo conhecedor: “Sua máquina não tem ROM básico”. E largou a máquina de lado por não ter a menor idéia do que, de fato, ocorria.

Porém, na maioria das vezes, o procedimento de inicialização encontrava um “disco de sistema”, ou seja, um disco que continha um “setor de boot” e os arquivos do sistema operacional (no tempo do PC esse disco teria obrigatoriamente que ser do tipo flexível, já que discos rígidos então não existiam; dois anos depois, a partir do advento do XT com seu suporte para discos rígidos, se não fosse encontrado um disquete com “setor de boot”, a busca prosseguia no disco rígido e em suas partições).

Encontrado um “setor de boot” (sempre o primeiro setor da primeira trilha do disquete ou unidade de disco rígido), o procedimento de inicialização localizava em seu interior uma rotina denominada “bootstrap code” (“código de bootstrap”, nome que foi dado por razões que já estamos fartos de conhecer), a carregava na memória RAM e passava o controle para ela “apontando” o PI para seu endereço inicial na MP.

Se você está acompanhando a descrição do procedimento de inicialização atentamente certamente reparou que até precisamente este momento todas as rotinas executadas residem em chips de memória não volátil (no PC, em memória permanente do tipo ROM). É somente após carregar o “bootstrap code” que o sistema passa a ler instruções na memória RAM.

Mas em que consiste exatamente o “bootstrap code”? Bem, sabendo-se que um setor abriga apenas 512 bytes e que o “bootstrap code” ocupa apenas uma parte do setor de boot (o restante é ocupado por dados de identificação do disco ou partição), não se pode esperar que ele faça muita coisa. Mas na verdade ele opera maravilhas, já que “sabe” que arquivos compõem o sistema operacional, onde eles estão armazenados em disco e como (e onde) carregá-los na memória RAM. Ou seja: o pequeno “bootstrap code” é o verdadeiro responsável pela carga do sistema operacional. E faz justamente isso: procura no disco os arquivos que compõem o SO (no caso do DOS, o IO.SYS e o MSDOS.SYS para o DOS desenvolvido pela Microsoft, ou IBMBIO.COM e IBMDOS.COM para o DOS desenvolvido pela IBM; o DRDOS da Digital Research ainda não havia sido desenvolvido) e os copia para a memória. No final, “aponta” o PI para o endereço das rotinas de inicialização do sistema que verifica se a tabela de vetores de interrupção foi de fato previamente carregada, verifica a memória disponível, verifica quais dispositivos necessitam de extensões do SO para serem controlados (essas extensões são conhecidas pelo nome de “drivers de dispositivo”), as carrega na memória RAM e cria estruturas de memória (buffers, pilhas, etc.) que serão usadas pelo SO. Depois executa outras tarefas auxiliares, como a leitura e execução dos comandos dos arquivos de configuração (Config.Sys e Autoexec.Bat). Finalmente, carrega um programeto pequeno mas muito útil, o processador de comandos “Command.Com”, responsável pela exibição do “prompt” do DOS e pela interpretação e execução de comandos, inclusive a carga de outros programas.

Neste ponto a máquina está desperta, alerta e pronta para ser usada.

E, como se viu, embora um bocado de coisas tenham sido feitas para pô-la (pôla!!! Que língua, a nossa...) em condições de uso, definitivamente não foi preciso apelar para qualquer milagre.

 

B. Piropo