Linuxhard.org

7 anos de Linux no Brasil – Dicas, Artigos e Notícias de Linux e Hardware
  • Início
  • Resulinux
  • KDuXP
  • Baixe Agora
  • Versões em Teste
  • Screenshots
  • Fórum
  • Quem somos?
  • Wiki

Hardware: Como funciona o sistema de boot

Luciano Andress Martini | 8 de outubro de 2009
Easy AdSense by Unreal

(baseado no trabalho da Hacker Vovó Vicki)

Quando o computador é ligado ou reiniciado, a BIOS executa um teste conhecido como POST (Power On Self Test). O POST verifica toda a memória, testa todas as placas e o hardware é rastreado. É através do POST que o computador é informado do número e dos tipos de placas, de drives de disquete, de HDs, de portas seriais, paralelas e USBs, do monitor, do mouse, do teclado, etc.

Após o sistema completar o POST, a interrupção 19 (INT 19) é chamada.

A INT 19 irá requisitar que o processador tente inicializar um sistema operacional lendo um setor de boot. Se for encontrado um setor de boot no disquete, este é lido e transferido para a memória no endereço 0000:7C00 e a INT 19 salta para o endereço de memória 0000:7C00.
Entretanto a BIOS não pode acessar as partições de um disco rigido sozinho, precisando carregar um pequeno programa que fica armazenado na MBR(446 bytes dos primeiros setores do MBR) e o pequeno programa tentará localizar as partições.
Cada sistema operacional possui um formato de setor de boot próprio. O pequeno programa no setor de boot precisa localizar a porção inicial do programa carregador (loader) do kernel do sistema operacional (ou, talvez, o próprio kernel ou um “programa gerenciador de boot”) e transferi-lo para a memória.

A INT 19 também é chamada quando as teclas Ctrl+Alt+Del são pressionadas simultaneamente. Na maioria dos sistemas, Ctrl+Alt+Del disparam uma versão reduzida do POST, que é executada antes da chamada à INT 19.

Dissecando o setor de boot

Para começar, coloco abaixo o boot de um sistema operacional clássico similar ao MS-DOS(R), note que não usei Linux para facilitar as coisas ;-) já que você não quer ficar maluco certo? (Você pode conseguir o mesmo usando um editor hexadecimal abrindo o IO.SYS de seu Freedos por exemplo)

  • O BPB (BIOS Parameter Block) começa no deslocamento (offset) 0.
  • O programa do setor de boot começa no deslocamento 3E.
  • As mensagens fornecidas pelo programa começam no deslocamento 19E.
  • O nomes dos arquivos ocultos do DOS começam no deslocamento 1E6.
  • A assinatura do setor de boot está no deslocamento 1FE.

OFFSET 0 1 2 3 4 5 6 7 8 9 A B C D E F *0123456789ABCDEF*
000000 eb3c904d 53444f53 352e3000 02010100 *...MSDOS5.0.....*
000010 02e00040 0bf00900 12000200 00000000 *...@............*
000020 00000000 0000295a 5418264e 4f204e41 *......)ZT..NO NA*
000030 4d452020 20204641 54313220 2020fa33 *ME FAT12 .3*
000040 c08ed0bc 007c1607 bb780036 c5371e56 *.....|...x.6.7.V*
000050 1653bf3e 7cb90b00 fcf3a406 1fc645fe *.S..|.........E.*
000060 0f8b0e18 7c884df9 894702c7 073e7cfb *....|.M..G....|.*
000070 cd137279 33c03906 137c7408 8b0e137c *..ry3.9..|t....|*
000080 890e207c a0107cf7 26167c03 061c7c13 *.. |..|...|...|.*
000090 161e7c03 060e7c83 d200a350 7c891652 *..|...|....P|..R*
0000a0 7ca3497c 89164b7c b82000f7 26117c8b *|.I|..K|. ....|.*
0000b0 1e0b7c03 c348f7f3 0106497c 83164b7c *..|..H....I|..K|*
0000c0 00bb0005 8b16527c a1507ce8 9200721d *......R|.P|...r.*
0000d0 b001e8ac 0072168b fbb90b00 bee67df3 *.....r........}.*
0000e0 a6750a8d 7f20b90b 00f3a674 18be9e7d *.u... .....t...}*
0000f0 e85f0033 c0cd165e 1f8f048f 4402cd19 *._.3...^....D...*
000100 585858eb e88b471a 48488a1e 0d7c32ff *XXX...G.HH...|2.*
000110 f7e30306 497c1316 4b7cbb00 07b90300 *....I|..K|......*
000120 505251e8 3a0072d8 b001e854 00595a58 *PRQ.:.r....T.YZX*
000130 72bb0501 0083d200 031e0b7c e2e28a2e *r..........|....*
000140 157c8a16 247c8b1e 497ca14b 7cea0000 *.|..$|..I|.K|...*
000150 7000ac0a c07429b4 0ebb0700 cd10ebf2 *p....t).........*
000160 3b16187c 7319f736 187cfec2 88164f7c *;..|s..6.|....O|*
000170 33d2f736 1a7c8816 257ca34d 7cf8c3f9 *3..6.|..%|.M|...*
000180 c3b4028b 164d7cb1 06d2e60a 364f7c8b *.....M|.....6O|.*
000190 ca86e98a 16247c8a 36257ccd 13c30d0a *.....$|.6%|.....*
0001a0 4e6f6e2d 53797374 656d2064 69736b20 *Non-System disk *
0001b0 6f722064 69736b20 6572726f 720d0a52 *or disk error..R*
0001c0 65706c61 63652061 6e642070 72657373 *eplace and press*
0001d0 20616e79 206b6579 20776865 6e207265 * any key when re*
0001e0 6164790d 0a00494f 20202020 20205359 *ady...IO SY*
0001f0 534d5344 4f532020 20535953 000055aa *SMSDOS SYS..U.*

A seguir, o código em traduzido para Assembly da Hacker Vovó Vicky para inicialização de um sistema operacional em modo 16 bits:

INICIO: INÍCIO DO PROGRAMA DO SETOR DE BOOT

0000:7C3E FA CLI desliga as interrupções
0000:7C3F 33C0 XOR AX,AX zera AX
0000:7C41 8ED0 MOV SS,AX SS agora é zero
0000:7C43 BC007C MOV SP,7C00 SP agora é 7C00
0000:7C46 16 PUSH SS põe zero na pilha
0000:7C47 07 POP ES e zera ES

O vetor da INT 1E etá em 0000:0078.
Pega o endereço apontado pelo vetor
e o coloca nos registradores DS:SI.

0000:7C48 BB7800 MOV BX,0078 BX agora é 78
0000:7C4B 36 SS:
0000:7C4C C537 LDS SI,[BX] DS:SI agora é [0:78]
0000:7C4E 1E PUSH DS salva DS:SI –
0000:7C4F 56 PUSH SI salva end tab param
0000:7C50 16 PUSH SS salva SS:BX –
0000:7C51 53 PUSH BX salva end da INT 1E

Move a tabela de parâmetros do
disquete para 0000:7C3E.

0000:7C52 BF3E7C MOV DI,7C3E DI é o endereço de START
0000:7C55 B90B00 MOV CX,000B contador é 11
0000:7C58 FC CLD limpa a direção
0000:7C59 F3 REPZ move a tabela de parâmetros
0000:7C5A A4 MOVSB do disquete para 0000:7C3E
0000:7C5B 06 PUSH ES também zera
0000:7C5C 1F POP DS DS

Altera alguns dados da tabela de
parâmetros do disquete.

0000:7C5D C645FE0F MOV BYTE PTR [DI-02],0F muda o tempo de ajuste
da cabeça em 0000:7C47
0000:7C61 8B0E187C MOV CX,[7C18] setores por trilha
0000:7C65 884DF9 MOV [DI-07],CL salva em 0000:7C42

Muda INT 1E para que aponte para a tabela de
parâmetros do disquete alterada em 0000:7C3E

0000:7C68 894702 MOV [BX+02],AX muda segmento da INT 1E
0000:7C6B C7073E7C MOV WORD PTR [BX],7C3E muda deslocamento
da INT 1E

Chama INT 13 com AX=0000, reset de disco, de
modo que a nova tabela de parâmetros do
disquete seja usada.

0000:7C6F FB STI liga as interruções
0000:7C70 CD13 INT 13 faz chamada do reset do
disquete
0000:7C72 7279 JB TALK salta se houver erro

Detemina o endereço inicial do setor do
diretório raiz como um LBA.

0000:7C74 33C0 XOR AX,AX AX agora é zero
0000:7C76 3906137C CMP [7C13],AX néumero de setores zero?
0000:7C7A 7408 JZ SMALL_DISK sim
0000:7C7C 8B0E137C MOV CX,[7C13] número de setores
0000:7C80 890E207C MOV [7C20],CX salva em número gigante

DISCO_PEQUENO:

0000:7C84 A0107C MOV AL,[7C10] número de tabelas FAT
0000:7C87 F726167C MUL WORD PTR [7C16] número de setores FAT
0000:7C8B 03061C7C ADD AX,[7C1C] nro de setores escondidos
0000:7C8F 13161E7C ADC DX,[7C1E] nro de setores escondidos
0000:7C93 03060E7C ADD AX,[7C0E] nro de setores reservados
0000:7C97 83D200 ADC DX,+00 nro de setores reservados
0000:7C9A A3507C MOV [7C50],AX salva endereço inicial
0000:7C9D 8916527C MOV [7C52],DX do dir raiz (como LBA)
0000:7CA1 A3497C MOV [7C49],AX salva endereço inicial
0000:7CA4 89164B7C MOV [7C4B],DX do dir raiz (como LBA)

Determina o endereço de setor do primeiro
setor na área de dados como um LBA.

0000:7CA8 B82000 MOV AX,0020 tamanho de uma entrada de

diretório (32)
0000:7CAB F726117C MUL WORD PTR [7C11] nro de entradas do
diretório raiz
0000:7CAF 8B1E0B7C MOV BX,[7C0B] bytes por setor
0000:7CB3 03C3 ADD AX,BX
0000:7CB5 48 DEC AX
0000:7CB6 F7F3 DIV BX
0000:7CB8 0106497C ADD [7C49],AX soma ao endereço inicial
0000:7CBC 83164B7C00 ADC WORD PTR [7C4B],+00 do dir raiz (como LBA)

Transfere o primeiro setor do diretório raiz
para 0000:0500.

0000:7CC1 BB0005 MOV BX,0500 end para transferência
0000:7CC4 8B16527C MOV DX,[7C52] pega end inicial do
0000:7CC8 A1507C MOV AX,[7C50] dir raiz (como LBA)
0000:7CCB E89200 CALL CONVERT chama rotina de
conversão
0000:7CCE 721D JB TALK salta se houver erro
0000:7CD0 B001 MOV AL,01 ler 1 setor
0000:7CD2 E8AC00 CALL READ_SECTORS lê primeiro setor do
diretório raiz
0000:7CD5 7216 JB TALK salta se houver erro
0000:7CD7 8BFB MOV DI,BX end da primeira entrada
do diretório
0000:7CD9 B90B00 MOV CX,000B contador é 11
0000:7CDC BEE67D MOV SI,7DE6 end dos nomes de arquivos
0000:7CDF F3 REPZ é o “IO.SYS”?
0000:7CE0 A6 CMPSB
0000:7CE1 750A JNZ TALK não
0000:7CE3 8D7F20 LEA DI,[BX+20] end da próxima entrada do
diretório
0000:7CE6 B90B00 MOV CX,000B contador é 11
0000:7CE9 F3 REPZ é o “MSDOS.SYS”?
0000:7CEA A6 CMPSB
0000:7CEB 7418 JZ FOUND_FILES são iguais

FALA:

Mostra mensagem “Non-System disk…”,
espera usuário apertar uma tecla, restaura
o vetro da INT 1E e depois chama a INT 19
para iniciar o processo de boot novamente.

0000:7CED BE9E7D MOV SI,7D9E “Non-System disk…”
0000:7CF0 E85F00 CALL MSG_LOOP mostra mensagem
0000:7CF3 33C0 XOR AX,AX função INT 16
0000:7CF5 CD16 INT 16 lê teclado
0000:7CF7 5E POP SI pega o endereço do
0000:7CF8 1F POP DS vetor da INT 1E
0000:7CF9 8F04 POP [SI] restaura os dados do
0000:7CFB 8F4402 POP [SI+02] vetor da INT 1E
0000:7CFE CD19 INT 19 chama INT 19 para tentar
novamente

PREPARA_FALA:

0000:7D00 58 POP AX tira lixo da pilha
0000:7D01 58 POP AX tira lixo da pilha
0000:7D02 58 POP AX tira lixo da pilha
0000:7D03 EBE8 JMP TALK agora fala com o usuário

ARQUIVOS_ENCONTRADOS:

Trata o endereço de setor do primeiro setor
de IO.SYS.

0000:7D05 8B471A MOV AX,[BX+1A] pega nro do cluster
inicial
0000:7D08 48 DEC AX subtrai 1
0000:7D09 48 DEC AX subtrai 1
0000:7D0A 8A1E0D7C MOV BL,[7C0D] setores por cluster
0000:7D0E 32FF XOR BH,BH
0000:7D10 F7E3 MUL BX multiplica
0000:7D12 0306497C ADD AX,[7C49] adiciona o end inicial
0000:7D16 13164B7C ADC DX,[7C4B] do dir raiz (como LBA)

Transfere IO.SYS para a memória em 0000:0700.
IO.SYS tem comprimento de 3 setores.

0000:7D1A BB0007 MOV BX,0700 end de transferência
0000:7D1D B90300 MOV CX,0003 lê 3 setores

LOOP_DE_LEITURA:

Lê os primeiros 3 setores de IO.SYS
(IO.SYS muito mais do que 3 setores).

0000:7D20 50 PUSH AX salva AX
0000:7D21 52 PUSH DX salva DX
0000:7D22 51 PUSH CX salva CX
0000:7D23 E83A00 CALL CONVERT chama rotina de
conversão
0000:7D26 72D8 JB SETUP_TALK salta se houver erro
0000:7D28 B001 MOV AL,01 lê um setor
0000:7D2A E85400 CALL READ_SECTORS lê um setor
0000:7D2D 59 POP CX restaura CX
0000:7D2E 5A POP DX restaura DX
0000:7D2F 58 POP AX restaura AX
0000:7D30 72BB JB TALK salta se erro INT 13
0000:7D32 050100 ADD AX,0001 soma 1 ao end do setor
0000:7D35 83D200 ADC DX,+00 soma 1 ao end do setor
0000:7D38 031E0B7C ADD BX,[7C0B] incrementa o end de mem
com tamanho do setor
0000:7D3C E2E2 LOOP READ_LOOP lê próximo setor

Deixa informação nos registradoresAX, BX, CX
e DX para uso do IO.SYS. Finalmente, salta
para o IO.SYS em 0070:000.

0000:7D3E 8A2E157C MOV CH,[7C15] tipo de mídia
0000:7D42 8A16247C MOV DL,[7C24] número do drive
0000:7D46 8B1E497C MOV BX,[7C49] pega o end inicial do
0000:7D4A A14B7C MOV AX,[7C4B] dir raiz (como LBA)
0000:7D4D EA00007000 JMP 0070:0000 salta para 0070:0000

LOOP_MENSAGEM:

Esta rotina mostra uma mensagem usando a
INT 10, um caracter por vez.
O endereço da mensagem está em DS:SI.

0000:7D52 AC LODSB pega caracter da msg
0000:7D53 0AC0 OR AL,AL fim da mensagem?
0000:7D55 7429 JZ RETURN salta se sim
0000:7D57 B40E MOV AH,0E mostra um caracter
0000:7D59 BB0700 MOV BX,0007 atributos de vídeo
0000:7D5C CD10 INT 10 mostra um caracter
0000:7D5E EBF2 JMP MSG_LOOP faça novamente

CONVERTE:
Esta rotina converte um endereço de setor
(um LBA) num endereço CHS. O LBA está em
DX:AX.

0000:7D60 3B16187C CMP DX,[7C18] parte alta do LBA
maior que sectPerTrk?
0000:7D64 7319 JNB SET_CARRY salta se sim
0000:7D66 F736187C DIV WORD PTR [7C18] divide por
setores por trilha
0000:7D6A FEC2 INC DL soma 1 ao nro de setores
0000:7D6C 88164F7C MOV [7C4F],DL salva número de setores
0000:7D70 33D2 XOR DX,DX zera DX
0000:7D72 F7361A7C DIV WORD PTR [7C1A] div número de cabeças
0000:7D76 8816257C MOV [7C25],DL salva número de cabeças
0000:7D7A A34D7C MOV [7C4D],AX salva nro de cilindros
0000:7D7D F8 CLC limpa carry
0000:7D7E C3 RET retorna

SET_CARRY:

0000:7D7F F9 STC set carry

RETORNA:

0000:7D80 C3 RET retorna

LER_SETORES:

O chamador desta rotina fornece:
AL = número de setores a serem lidos
ES:BX = localização da mem para
transferência e
CHS endereço da leitura a ser transferida
para as localizações de memória 7C25 e

7C4D a 7C4F.

0000:7D81 B402 MOV AH,02 INT 13 lê setores
0000:7D83 8B164D7C MOV DX,[7C4D] pega nro de cilindros
0000:7D87 B106 MOV CL,06 shift contador
0000:7D89 D2E6 SHL DH,CL shift esq. cilindro mais
significativo 6 bits
0000:7D8B 0A364F7C OR DH,[7C4F] OR no número do setor
0000:7D8F 8BCA MOV CX,DX move para CX
0000:7D91 86E9 XCHG CH,CL CH=cilindro baixo,
CL=cilindro alto
+ setor
0000:7D93 8A16247C MOV DL,[7C24] número do drive
0000:7D97 8A36257C MOV DH,[7C25] número da cabeça
0000:7D9B CD13 INT 13 lê setores 0000:7D9D C3 RET retorna

Categorias
Hardware, Programação
Comentários RSS
Comentários RSS
Trackback
Trackback

« Importância e como fazer backup do MBR Apt-get / aptitude – O Guia definitivo contra Falhas »

Uma Resposta para “Hardware: Como funciona o sistema de boot”

  1. Mauroc disse:
    17 de maio de 2010 às 19:50

    Olá Luciano e sou o Mauro(amigo da Luana).

    Eu li o artigo mais ainda tenho algumas duvidas, e possível criar o arquivo, e tentar usa-lo em uma maquina virtual para fazer a simulação ?

Deixe uma Resposta

Clique aqui para cancelar a resposta.

Publicidade

Traduzir este Site

  • Categorias

    • Hardware (1)
    • Linux (13)
      • Sistema de Arquivos (1)
    • Mundo Software Livre (53)
    • Programação (4)
    • TI (2)

Arquivos

  • julho 2010
  • maio 2010
  • março 2010
  • fevereiro 2010
  • janeiro 2010
  • dezembro 2009
  • novembro 2009
  • outubro 2009
  • agosto 2009
  • julho 2009
  • maio 2009
  • abril 2009
  • março 2009
  • fevereiro 2009
  • janeiro 2009
  • dezembro 2008
  • novembro 2008
  • outubro 2008
  • setembro 2008
  • julho 2008

Links

  • br-linux
  • Portal Criativa
  • Ubuntu-BR

Parceiros

Administração

  • Registrar-se
  • Login
  • Posts RSS
  • RSS dos comentários
  • WordPress.org
rss Comentários RSS valid xhtml 1.1 design by jide powered by Wordpress get firefox by webmaster