<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>GilgaLab &#187; Assembly</title>
	<atom:link href="http://www.gilgalab.com.br/category/assembly/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gilgalab.com.br</link>
	<description></description>
	<lastBuildDate>Mon, 07 Nov 2011 07:38:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Bootstrap Simples</title>
		<link>http://www.gilgalab.com.br/2007/11/02/bootstrap-simples/</link>
		<comments>http://www.gilgalab.com.br/2007/11/02/bootstrap-simples/#comments</comments>
		<pubDate>Fri, 02 Nov 2007 23:41:15 +0000</pubDate>
		<dc:creator>Henrique</dc:creator>
				<category><![CDATA[Assembly]]></category>
		<category><![CDATA[Sistemas Operacionais]]></category>

		<guid isPermaLink="false">http://artofcoding.wordpress.com/2007/11/02/bootstrap-simples/</guid>
		<description><![CDATA[Introdução Esse fim de semana andei estudando um pouco de assembly. Decidi fazer um bootstrap para ver se me animava um pouco, e acabou me voltando a vontade de realmente brincar de criar o meu sistema operacional. Como tudo precisa de um começo, decidi que o bootstrap seria um belo lugar para começar. Vejamos então [...]]]></description>
			<content:encoded><![CDATA[<p><b>Introdução</b></p>
<p>Esse fim de semana andei estudando um pouco de assembly. Decidi fazer um bootstrap para ver se me animava um pouco, e acabou me voltando a vontade de realmente brincar de criar o meu sistema operacional. Como tudo precisa de um começo, decidi que o bootstrap seria um belo lugar para começar.<br />
Vejamos então como é que fazemos para dar um boot na maquina e o que é que a(o) BIOS (Basic Input Output System) espera para iniciar o sistema operacional.<br />
Quando o computador inicia e o POST termina, a BIOS faz uma chamada para ler o primeiro setor do disco que está definido como primário no setup. Funciona assim:</p>
<p>a) Olha o primeiro setor do disco definido no setup<br />
b) Encontrou setor de boot válido?<br />
c) Sim. Lê o setor e carrega o código para o <del>segmento</del> endereço 7C00h na memória. (Valeu pela correção Muzgo :)<br />
d) Não. Parte para o próximo dispositivo da lista de boot e vai para a) até encontrar.<br />
e) Caso não encontre em nenhum dos dispositivos, exibe mensagem de erro padrão da BIOS.</p>
<p>A Lista de software que usei:<br />
1. NASM - Para compilar o código<br />
2. QEMU - Maquina virtual que uso para testar o setor de boot<br />
3. dd   - Utilizado para escrever os dados no disco</p>
<p><b>O setor de boot</b></p>
<p>Quando definimos o disco no qual desejamos dar o boot, a BIOS chama uma interrupção (19h se nao me engano), para ler o primeiro setor desse disco. O primeiro setor é o que se encontra na posição CHS (Cylinder Head Sector) 0:0:1. Cada setor no disco tem 512 bytes, então como a BIOS lê o primeiro setor do disco, nosso 'programa' precisa ter 512 bytes ou menos. Meu objetivo aqui não é de falar muito sobre HCS, maiores informações você pode encontrar <a href="http://en.wikipedia.org/wiki/Cylinder-head-sector">aqui</a>.<br />
O que identifica se temos um setor de boot válido ou não?<br />
O setor de boot tem uma 'assinatura', os últimos dois bytes do setor devem ser '0xAA55'. Quando essa assinatura é encontrada, os 512 bytes são carregados para a memória na posição 7C00h e o programa é executado.</p>
<p><b>O código</b></p>
<p>Como já diria o conde Drácula em 'Castlevania: Symphony of the Night': "Enough talk!".<br />
Vamos dar uma olhada então em um código bem simples, que imprime uma string na tela.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">; Boot.asm</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">ORG</span> <span style="color: #0000ff;">7C00h</span>                   <span style="color: #666666; font-style: italic;">; Posição onde estaremos quando o código for</span>
&nbsp;
                            <span style="color: #666666; font-style: italic;">; carregado para a memória</span>
&nbsp;
mymsg<span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">db</span> <span style="color: #7f007f;">'Olá Setor de BOOT'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">10</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0</span>
&nbsp;
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span><span style="color: #00007f;">ax</span>                   <span style="color: #666666; font-style: italic;">; Limpando ax</span>
&nbsp;
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">si</span><span style="color: #339933;">,</span>mymsg                <span style="color: #666666; font-style: italic;">; Nossa mensagem em SI</span>
&nbsp;
putstr<span style="color: #339933;">:</span>
        <span style="color: #00007f; font-weight: bold;">lodsb</span>               <span style="color: #666666; font-style: italic;">; Coloca o byte apontado em SI em AL, e incrementa</span>
                            <span style="color: #666666; font-style: italic;">; o contador</span>
&nbsp;
        <span style="color: #00007f; font-weight: bold;">or</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span><span style="color: #00007f;">al</span>            <span style="color: #666666; font-style: italic;">; Verificamos se encontramos o byte '0' da string</span>
        <span style="color: #00007f; font-weight: bold;">jz</span> hang<span style="color: #666666; font-style: italic;">;            ; Se sim, paramos de imprimir</span>
        <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ah</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0x0E</span>         <span style="color: #666666; font-style: italic;">; Função para escrever</span>
&nbsp;
        <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">bx</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0x0007</span>       <span style="color: #666666; font-style: italic;">; Define a página e a cor onde escrevemos</span>
        <span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x10</span>            <span style="color: #666666; font-style: italic;">; Interrupção de video</span>
        <span style="color: #00007f; font-weight: bold;">jmp</span> putstr          <span style="color: #666666; font-style: italic;">; Imprimir proximo caracter</span>
&nbsp;
hang<span style="color: #339933;">:</span>
        <span style="color: #00007f; font-weight: bold;">jmp</span> hang            <span style="color: #666666; font-style: italic;">; Após impressão, entramos em loop infinito</span>
&nbsp;
times <span style="color: #0000ff;">512</span><span style="color: #339933;">-</span><span style="color: #009900; font-weight: bold;">&#40;</span>$<span style="color: #339933;">-</span>$$<span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">-</span><span style="color: #0000ff;">2</span> <span style="color: #000000; font-weight: bold;">DB</span> <span style="color: #0000ff;">0</span>     <span style="color: #666666; font-style: italic;">; Preenchemos o resto da memória com '0's</span>
&nbsp;
                            <span style="color: #666666; font-style: italic;">; até 510 bytes</span>
<span style="color: #000000; font-weight: bold;">DW</span> <span style="color: #0000ff;">0xAA55</span>                   <span style="color: #666666; font-style: italic;">; Assinatura do setor de boot</span></pre></div></div>

<p>Acredito que o código esteja auto explicativo. Você deve precisar manjar um pouco de assembly, então se não entendeu o código, procure estudar um pouquinho de assembly.<br />
Vamos agora compilar o nosso código, criar um disco para o QEMU, e escrever o nosso setor de boot no disco.</p>
<p>$ nasm boot.asm -f bin -o boot.bin<br />
$ qemu-img create /tmp/boot.img -f qcow 1M<br />
$ dd if=boot.bin of=/tmp/boot.img</p>
<p>Com isso feito, basta agora executar o QEMU e dizer que desejamos usar o arquivo /tmp/boot.img como nosso disco.</p>
<p>$ qemu /tmp/boot.img -m 16</p>
<p>O resultado é a nossa frase impressa logo após a BIOS fazer o POST.</p>
<p><b>Colocando código no Disco</b></p>
<p>Bom, agora que já sabemos dar o boot, está na hora de colocarmos código no disco e executar esse código. Esse é um processo um pouco mais complicado, mas vamos que vamos!<br />
A idéia agora é fazer com que o nosso programa de boot chame um binario que esteja gravado no disco e o execute. Então precisaremos escrever dois programas distintos: Um para ser o nosso setor de boot, e um que será chamado por ele. "Show me the code"</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">; Boot2.asm</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">ORG</span> <span style="color: #0000ff;">7C00h</span>
&nbsp;
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">si</span><span style="color: #339933;">,</span>msg
&nbsp;
prntMsg<span style="color: #339933;">:</span>                    <span style="color: #666666; font-style: italic;">; Imprime a mensagem em SI</span>
  <span style="color: #00007f; font-weight: bold;">lodsb</span>
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ah</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0x0E</span>
&nbsp;
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">bx</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0x0007</span>
  <span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">10h</span>
  <span style="color: #00007f; font-weight: bold;">or</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span><span style="color: #00007f;">al</span>
&nbsp;
  <span style="color: #00007f; font-weight: bold;">jnz</span> prntMsg
&nbsp;
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #009900; font-weight: bold;">&#91;</span>drv<span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span><span style="color: #00007f;">dl</span>                <span style="color: #666666; font-style: italic;">; DL contém o identificador da unidade em que </span>
                            <span style="color: #666666; font-style: italic;">; o setor de boot foi encontrado</span>
&nbsp;
<span style="color: #666666; font-style: italic;">; Inicializar o disco. Aqui colocamos a cabeça do disco no inicio dele</span>
&nbsp;
<span style="color: #339933;">.</span>diskSetup
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0</span>        <span style="color: #666666; font-style: italic;">; Função para resetar o disco rígido</span>
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">dl</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">&#91;</span>drv<span style="color: #009900; font-weight: bold;">&#93;</span>    <span style="color: #666666; font-style: italic;">; O drive que vamos resetar</span>
&nbsp;
  <span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">13h</span>         <span style="color: #666666; font-style: italic;">; Chama a interrupção de disco</span>
  <span style="color: #00007f; font-weight: bold;">jc</span> <span style="color: #339933;">.</span>diskSetup   <span style="color: #666666; font-style: italic;">; Se der erro, tentamos de novo</span>
&nbsp;
<span style="color: #666666; font-style: italic;">; Após resetar o disco, colocaremos a cabeça no setor que o programa se </span>
&nbsp;
<span style="color: #666666; font-style: italic;">; encontra e carregamos o programa na memória</span>
&nbsp;
<span style="color: #339933;">.</span>diskRead
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ah</span><span style="color: #339933;">,</span><span style="color: #0000ff;">02h</span>    <span style="color: #666666; font-style: italic;">; Função para ler o disco</span>
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span><span style="color: #0000ff;">3</span>      <span style="color: #666666; font-style: italic;">; Ler 3 setores (512 * 3 bytes)</span>
&nbsp;
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ch</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0</span>      <span style="color: #666666; font-style: italic;">; Apontar para o cilindro 0</span>
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">cl</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0x02</span>   <span style="color: #666666; font-style: italic;">; Ler a partir do setor 2 (2, 3 e 4)</span>
&nbsp;
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">dh</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0</span>      <span style="color: #666666; font-style: italic;">; Cabeça 0</span>
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">dl</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">&#91;</span>drv<span style="color: #009900; font-weight: bold;">&#93;</span>  <span style="color: #666666; font-style: italic;">; Disco de onde queremos ler os dados</span>
&nbsp;
<span style="color: #666666; font-style: italic;">; Os dados que lemos com essa função são armazenados em ES:BX</span>
<span style="color: #666666; font-style: italic;">; No nosso caso aqui entao teremos 1000h:0</span>
&nbsp;
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">bx</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0x1000</span>
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">es</span><span style="color: #339933;">,</span><span style="color: #00007f;">bx</span>
&nbsp;
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">bx</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0</span>
&nbsp;
  <span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">13h</span>       <span style="color: #666666; font-style: italic;">; Interrupção do disco</span>
  <span style="color: #00007f; font-weight: bold;">jc</span> <span style="color: #339933;">.</span>diskRead  <span style="color: #666666; font-style: italic;">; Em caso de erro, tenta de novo</span>
&nbsp;
<span style="color: #00007f; font-weight: bold;">jmp</span> <span style="color: #0000ff;">1000h</span><span style="color: #339933;">:</span><span style="color: #0000ff;">0</span><span style="color: #666666; font-style: italic;">;    ; Aqui nós pulamos para o nosso código que acaba de ser</span>
                <span style="color: #666666; font-style: italic;">; carregado na memória</span>
&nbsp;
hang<span style="color: #339933;">:</span>
  <span style="color: #00007f; font-weight: bold;">jmp</span> hang      <span style="color: #666666; font-style: italic;">; Loop infinito</span>
&nbsp;
drv <span style="color: #000000; font-weight: bold;">db</span> <span style="color: #0000ff;">0</span>
msg <span style="color: #000000; font-weight: bold;">db</span> <span style="color: #7f007f;">'Chamando programa do HD'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">13</span><span style="color: #339933;">,</span><span style="color: #0000ff;">10</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0</span>
&nbsp;
times <span style="color: #0000ff;">512</span><span style="color: #339933;">-</span><span style="color: #009900; font-weight: bold;">&#40;</span>$<span style="color: #339933;">-</span>$$<span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">-</span><span style="color: #0000ff;">2</span> <span style="color: #000000; font-weight: bold;">db</span> <span style="color: #0000ff;">0</span>   <span style="color: #666666; font-style: italic;">; Completa o espaço do setor que sobra com 0s</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">DW</span> <span style="color: #0000ff;">0xAA55</span>                 <span style="color: #666666; font-style: italic;">; Assinatura do setor de boot nos ultimos dois bytes</span></pre></div></div>

<p>Esse código então, como da para perceber, lê o código do disco, coloca o código na posição de memória 1000h:0 e pula para lá para começar a execução. Bom, precisamos agora então do programa que desejamos ler do disco e executar. Esse programa, assim como o primeiro exemplo vai simplesmente imprimir uma mensagem na tela.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">;  Programa.asm</span>
&nbsp;
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">1000h</span>           <span style="color: #666666; font-style: italic;">; Atualizar os registros de segmentos</span>
&nbsp;
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ds</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ax</span>
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">es</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ax</span>
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">si</span><span style="color: #339933;">,</span> msg             <span style="color: #666666; font-style: italic;">; Mensagem em SI</span>
&nbsp;
putstr<span style="color: #339933;">:</span>
  <span style="color: #00007f; font-weight: bold;">lodsb</span>
  <span style="color: #00007f; font-weight: bold;">or</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span><span style="color: #00007f;">al</span>
  <span style="color: #00007f; font-weight: bold;">jz</span> hang
&nbsp;
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ah</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0x0E</span>
  <span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">bx</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0x0007</span>
  <span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x10</span>
&nbsp;
  <span style="color: #00007f; font-weight: bold;">jmp</span> putstr
&nbsp;
hang<span style="color: #339933;">:</span>
  <span style="color: #00007f; font-weight: bold;">jmp</span> hang
&nbsp;
msg     <span style="color: #000000; font-weight: bold;">db</span> <span style="color: #7f007f;">'Bla bla bla!'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">13</span><span style="color: #339933;">,</span><span style="color: #0000ff;">10</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0</span></pre></div></div>

<p>Nesse programa nós atualizamos os registros de segmento para o mesmo endereço onde carregamos o programa do nosso HD, e executamos a rotina basica de imprimir a mensagem na tela, e entrar em loop infinito.<br />
Para executar esse exemplo, os paso são parecidos. Vejamos:</p>
<p>$ nasm boot2.asm -f bin -o boot2.bin<br />
$ nasm programa.asm -f bin -o programa.bin<br />
$ qemu-img create ./boot2.img -f qcow 1M<br />
$ dd if=boot2.bin of=./boot2.img<br />
$ dd if=programa.bin of=./boot2.img bs=512 seek=1<br />
$ qemu ./boot.img -m 16</p>
<p>O comando '$ dd if=programa.bin of=./boot2.img bs=512 seek=1' coloca o nosso código no segundo setor do disco, pois conforme definimos em nosso código, é la que nosso bootstrap está esperando encontra-lo.</p>
<p><b>Conclusão</b><br />
Bom pessoal, é isso ai. Como o tpitulo disse, é um bootstrap simples, apenas para dar um gostinho de como funciona, e trazer mais animo para maiores pesquisas.<br />
Espero que tenham gostado e que possa ser útil para alguém.</p>
<p>Até o próxmo :D</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gilgalab.com.br/2007/11/02/bootstrap-simples/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

