Master Boot Record - ITIS "E. Fermi"

Transcript

Master Boot Record - ITIS "E. Fermi"
[Avanti] [Indietro] [Su] [Indice]
2.1.2 Il MBR - Master Boot Record
Il master boot record, o MBR, è il primo settore di un disco (cilindro 0, testina 0,
settore 1) ed è destinato a contenere le informazioni essenziali per l’avvio del
sistema (v. fig. 2.3).
Figura 2.3: Schematizzazione del MBR.
Come ogni settore del disco, il MBR ha una dimensione di 512 byte, di cui i
primi 446 sono destinati a contenere il MBP (Master Boot Program), cioè le
istruzioni da eseguire quando viene avviato il disco, mentre i rimanenti 66 byte
costituiscono la partition table, ovvero le informazioni sul partizionamento del
disco. In particolare la partition table vera e propria si compone di 4 elementi
(entry), di 16 byte l’uno, che descrivono le partizioni primarie (al massimo 4
partizioni primarie, o 3 primarie ed una estesa) in cui può essere suddiviso il
disco. Ogni elemento contiene le informazioni riportate nella tab. 2.1.
Tabella 2.1: Partition table entry.
pag. 1/12
Non è detto che i valori di testina, settore e cilindro del primo e dell’ultimo
blocco di ogni partizione siano ognuno memorizzati su un byte. Considerando
hard disk con capacità di 10 MiB, si possono avere architetture con 256 testine,
64 settori e 1220 cilindri. Pertanto il numero di testine sarà rappresentato
esattamente su un byte, mentre per i settori saranno sufficienti 6 bit, cosicché,
visto che un byte non sarebbe sufficiente per rappresentare i cilindri, vengono
utilizzati i 2 bit più significativi del byte che riporta i settori e considerati come i
2 bit più significativi da aggiungere ad un byte per formare così 10 byte per
memorizzare il numero di cilindri. Ma con 10 byte si possono memorizzare
soltanto valori da 0 a 1023. Quindi, per com’è stato realizzato il MBR, lo SBP
dovrebbe essere contenuto nei primi 1024 cilindri del disco (cioè nei primi 8
GiB), altrimenti il BIOS non sarà in grado di raggiungerlo e quindi il sistema
operativo non potrà essere caricato. Per ovviare questo problema, nelle
versioni
più
recenti
dei
BIOS
è
possibile
utilizzare
la
traduzione
dell’indirizzamento dei settori LBA (come accennato nella sez. 1.8). Questo
pemette di oltrepassare il limite sull’indirizzamento dei cilindri suddetto.
Gli ultimi 2 byte delle partition table sono un identificativo di riconoscimento
della fine del MBR e contengono il valore AA55H (si ricordi che i PC utilizzano
la convenzione little endian per la memorizzazione delle informazioni)4.
Un esempio del contenuto di un MBR è riportato di seguito (si tratta del
MBR di GRUB, v. sez. 2.1.6).
pag. 2/12
00000000
eb 48 90 d0 bc 00 7c fb
50 07 50 1f fc be 1b 7c
|.H....|.P.P...
00000010
bf 1b 06 50 57 b9 e5 01
f3 a4 cb be be 07 b1 04
|...PW.........
00000020
38 2c 7c 09 75 15 83 c6
10 e2 f5 cd 18 8b 14 8b
|8,|.u.........
00000030
ee 83 c6 10 49 74 16 38
2c 74 f6 be 10 07 03 02
|....It.8,t....
00000040
80 00 00 80 64 6b ce 00
00 08 fa ea 50 7c 00 00
|....dk......P|
00000050
31 c0 8e d8 8e d0 bc 00
20 fb a0 40 7c 3c ff 74
|1....... ..@|<
00000060
02 88 c2 52 be 76 7d e8
34 01 f6 c2 80 74 54 b4
|...R.v}.4....t
00000070
41 bb aa 55 cd 13 5a 52
72 49 81 fb 55 aa 75 43
|A..U..ZRrI..U.
00000080
a0 41 7c 84 c0 75 05 83
e1 01 74 37 66 8b 4c 10
|.A|..u....t7f.
00000090
be 05 7c c6 44 ff 01 66
8b 1e 44 7c c7 04 10 00
|..|.D..f..D|..
000000a0
c7 44 02 01 00 66 89 5c
08 c7 44 06 00 70 66 31
|.D...f.\..D..p
000000b0
c0 89 44 04 66 89 44 0c
b4 42 cd 13 72 05 bb 00
|..D.f.D..B..r.
000000c0
70 eb 7d b4 08 cd 13 73
0a f6 c2 80 0f 84 f3 00
|p.}....s......
000000d0
e9 8d 00 be 05 7c c6 44
ff 00 66 31 c0 88 f0 40
|.....|.D..f1..
000000e0
66 89 44 04 31 d2 88 ca
c1 e2 02 88 e8 88 f4 40
|f.D.1.........
000000f0
89 44 08 31 c0 88 d0 c0
e8 02 66 89 04 66 a1 44
|.D.1......f..f
00000100
7c 66 31 d2 66 f7 34 88
54 0a 66 31 d2 66 f7 74
||f1.f.4.T.f1.f
00000110
04 88 54 0b 89 44 0c 3b
44 08 7d 3c 8a 54 0d c0
|..T..D.;D.}<.T
00000120
e2 06 8a 4c 0a fe c1 08
d1 8a 6c 0c 5a 8a 74 0b
|...L......l.Z.
00000130
bb 00 70 8e c3 31 db b8
01 02 cd 13 72 2a 8c c3
|..p..1......r*
00000140
8e 06 48 7c 60 1e b9 00
01 8e db 31 f6 31 ff fc
|..H|`......1.1
00000150
f3 a5 1f 61 ff 26 42 7c
be 7c 7d e8 40 00 eb 0e
|...a.&B|.|}.@.
00000160
be 81 7d e8 38 00 eb 06
be 8b 7d e8 30 00 be 90
|..}.8.....}.0.
00000170
7d e8 2a 00 eb fe 47 52
55 42 20 00 47 65 6f 6d
|}.*...GRUB .Ge
00000180
00 48 61 72 64 20 44 69
73 6b 00 52 65 61 64 00
|.Hard Disk.Rea
00000190
20 45 72 72 6f 72 00 bb
01 00 b4 0e cd 10 ac 3c
| Error........
000001a0
00 75 f4 c3 00 00 00 00
00 00 00 00 00 00 00 00
|.u............
000001b0
00 00 00 00 00 00 00 00
00 00 00 00 00 00 80 01
|..............
000001c0
01 00 0b fe ff 47 3f 00
00 00 09 e9 cd 00 00 00
|.....G?.......
000001d0
c1 48 83 fe ff 51 48 e9
cd 00 8a 73 02 00 00 00
|.H...QH....s..
000001e0
c1 52 83 fe ff ff d2 5c
d0 00 54 58 53 00 00 fe
|.R.....\..TXS.
000001f0
ff ff 0f fe ff ff 26 b5
23 01 20 d8 07 00 55 aa
|......&.#. ...
Prima di effettuare qualsiasi operazione sul MBR è caldamente consigliato di
effettuarne una copia di backup in modo da poterlo eventualmente rirpistinare
nel caso in cui le modifiche effettuate dessero dei problemi. Il backup e
l’eventuale ripristino del MBR può essere effettuato per mezzo del comando dd
(man page dd(1)) che copia fisicamente i byte da un media in un altro.
____________________________________________________________________
Comando: dd
Path: /bin/dd
SINTASSI
# dd [option]
DESCRIZIONE
option indica la modalità di funzionamento di dd. Può assumere i seguenti
valori:
bs=bytes specifica la dimensione dei blocchi di lettura e scrittura secondo
quanto indicato da bytes;
cbs=bytes specifica la dimensione dei blocchi nella conversione secondo
quanto indicato da bytes;
conv=type specifica la conversione da effettuare sui byte letti secondo quanto
indicato da type (v. tab. 2.2);
pag. 3/12
Tabella 2.2: Conversioni effettuabili con dd.
count=num specifica il numero di blocchi da leggere secondo quanto indicato
da num;
ibs=bytes specifica la dimensione dei blocchi di lettura secondo quanto
indicato da bytes;
if=file specifica il file dal quale leggere, secondo quanto indicato da file (se
non viene indicato viene considerato lo standard input);
obs=bytes specifica la dimensione dei blocchi di scrittura secondo quanto
indicato da bytes;
of=file specifica il file nel quale scrivere, secondo quanto indicato da file (se
non viene indicato viene considerato lo standard output);
seek=num specifica di saltare num blocchi in scrittura;
skip=num specifica di saltare num blocchi in lettura;
--help visualizza un aiuto sommario di dd;
--version visualizza la versione di dd;
bytes e num possono essere valori numerici seguiti dai suffissi moltiplicativi illustrati
nella tab. 2.3.
pag. 4/12
Tabella 2.3: Suffissi utilizzabili con dd.
________________________________________________________________________
Le informazioni contenute nel MBR di un disco possono essere salvate in
un file con un comando analogo a quello seguente
# dd if=/dev/hda of=/boot/boot.MBR bs=512 count=1
In questo modo vengono fisicamente copiati i byte contenuti nel primo settore
(512 byte) del primo disco ATA (/dev/hda) nel file /boot/boot.MBR.
Per ripristinare successivamente il MBR con le informazioni contenute in un
file si può utilizzare il comando seguente
# dd if=/boot/boot.MBR of=/dev/hda bs=512 count=1
In questo modo vengono rimpiazzati i byte contenuti nel primo settore (512
byte) del primo disco ATA (/dev/hda) con quelli contenuti nel
file /boot/boot.MBR. Così facendo viene ripristinato quindi sia il MBP che la
partition table. Nel caso in cui non si voglia ripristinare la partition table occorre
ripristinare soltanto i primi 446 byte del MBR (ovvero non considerare gli ultimi
pag. 5/12
66 byte, contenenti appunto la partition table), con il seguente comando
# dd if=/boot/boot.MBR of=/dev/hda bs=446 count=1
È possibile ripristinare il MBR anche da DOS, lanciando il comando
C:\>FDISK /MBR
oppure
C:\>FIXMBR
dipendentemente dallo specifico sistema operativo considerato.
È evidente che per far ciò deve essere possibile avviare il sistema. Visto che il
MBR è il settore di boot necessario per l’avvio del sistema, è opportuno creare
un dischetto di avvio, in maniera da poter avviare il sistema senza aver bisogno
del MBR, come descritto nella sez. 2.1.3.
Subito dopo il POST, viene generalmente chiamato l’interrupt 19H, che tenta
di leggere il boot sector dal primo disco avviabile (in genere la sequenza dei
dischi consultati per l’avvio è: floppy disk, CD-ROM, hard disk). Il primo settore
di boot disponibile (nella sequenza dei dispositivi consultati) viene caricato in
memoria a partire dalla locazione 7C00H e viene eseguito (il registro SI viene
inizializzato con il valore dell’indirizzo della prima locazione relativa alla riga
della partition table che descrive la partizione dalla quale è stato caricato il boot
record).
Se la word contenuta a partire dalla locazione 0000 : 0472H è diversa
da 1234H l’interrupt 19H effettuerà un test della memoria centrale prima
di caricare il boot sector.
Il boot di un sistema basato su architettura Intel X386 è un processo piuttosto
complesso, poiché inizialmente la CPU funziona in modalità reale5, potendo
pag. 6/12
accedere soltanto al primo MiB di memoria, quindi il boot loader caricherà il
sistema operativo (nel caso di GNU/Linux, si tratta del kernel) all’interno del
primo MiB di memoria, che una volta avviato in esecuzione, provvederà a far
passare la CPU alla modalità protetta e quindi avere a disposizione tutta la
memoria fisicamente installata sul sistema.
Di seguito sono riportate, sia la parte dati che le istruzioni assembly X386
(v. cap. 15), secondo lo standard Intel, corrispondenti al codice macchina del
MBR visto precedentemente (già rilocato a partire dall’indirizzo 7C00H), per
meglio illustrarne il funzionamento.
0000:7c00
eb 48 90 d0 bc 00 7c fb
50 07 50 1f fc be 1b 7c
|.H....|.P.P..
0000:7c10
bf 1b 06 50 57 b9 e5 01
f3 a4 cb be be 07 b1 04
|...PW........
0000:7c20
38 2c 7c 09 75 15 83 c6
10 e2 f5 cd 18 8b 14 8b
|8,|.u........
0000:7c30
ee 83 c6 10 49 74 16 38
2c 74 f6 be 10 07 03 02
|....It.8,t...
0000:7c40
80 00 00 80 64 6b ce 00
00 08 fa ea 50 7c 00 00
|....dk......P
0000:7d70
7d e8 2a 00 eb fe 47 52
55 42 20 00 47 65 6f 6d
|}.*...GRUB .G
0000:7d80
00 48 61 72 64 20 44 69
73 6b 00 52 65 61 64 00
|.Hard Disk.Re
0000:7d90
20 45 72 72 6f 72 00 bb
01 00 b4 0e cd 10 ac 3c
| Error.......
0000:7da0
00 75 f4 c3 00 00 00 00
00 00 00 00 00 00 00 00
|.u...........
0000:7db0
00 00 00 00 00 00 00 00
00 00 00 00 00 00 80 01
|.............
0000:7dc0
01 00 0b fe ff 47 3f 00
00 00 09 e9 cd 00 00 00
|.....G?......
0000:7dd0
c1 48 83 fe ff 51 48 e9
cd 00 8a 73 02 00 00 00
|.H...QH....s.
0000:7de0
c1 52 83 fe ff ff d2 5c
d0 00 54 58 53 00 00 fe
|.R.....\..TXS
0000:7df0
ff ff 0f fe ff ff 26 b5
23 01 20 d8 07 00 55 aa
|......&.#. ..
0000:7c00
eb 48
jmp
0x7c4a
Continua
l’esecuzione dalla locazione 7C4AH
Inizio
0000:7c4a fa
Disabilita gli
cli
interrupt
0000:7c4b
ea 50 7c 00 00
l’esecuzione dalla locazione 0000 : 7C50
ljmp
H.
0x0,0x7c50
Continua
Questo serve perché altrimenti certi BIOS possono
dare problemi
0000:7c50 31 c0
xor
ax,ax
Azzera AX
0000:7c52 8e d8
mov
ds,ax
Azzera DS
0000:7c54 8e d0
mov
ss,ax
Azzera SS
0000:7c56 bc 00 20
mov
sp,0x2000
SP = 2000H
0000:7c59 fb
interrupt
pag. 7/12
sti
Abilita gli
0000:7c5a a0 40 7c
Check if we
mov
al,ds:0x7c40
cmp
al,0xff
Confronta AL
je
0x7c63
Se AL è 80H,
mov
dl,al
DL = AL
have a forced disk reference here
0000:7c5d 3c ff
con FFH
0000:7c5f 74 02
Invalid drive: continua l’esecuzione da 7C63H
0000:7c61 88 c2
0000:7c63
52
push
Salva DX
dx
nello stack
Visualizza il messaggio “GRUB ”
0000:7c64 be 76 7d
mov
si,0x7d76
0x7d9e
Chiama la
test
dl,0x80
Esegui l’AND
je
0x7cc3
Se l’AND ha
0000:7c67 e8 34 01
call
routine di visualizzazione che inizia a 7D9EH
0000:7c6a f6 c2 80
tra DL e 80
H
0000:7c6d 74 54
dato come risultato 0, non si tratta di un HD: continua l’esecuzione da 7CC3H
Prova con il supporto LBA
0000:7c6f b4 41
mov
ah,0x41
0000:7c71 bb aa 55
mov
bx,0x55aa
0000:7c74 cd 13
int
0x13
Chiama la
routine di interrupt 13H (AH=41H), che testa il supporto LBA del BIOS
0000:7c76 5a
pop
Ripristina il
dx
contenuto di DX con quello salvato nello stack (con alcuni BIOS il contenuto di DL potrebbe essere
variato dopo la chiamata all’interrupt 13H)
0000:7c77 52
0000:7c78
push
72 49
jb
supportato: continua da 7CC3
H
0x7cc3
cmp
75 43
bx,0xaa55
jne
supportato: continua da 7CC3
H
LBA non
(prova con CHS)
0000:7c7a 81 fb 55 aa
0000:7c7e
dx
0x7cc3
LBA non
(prova con CHS)
Test se AH=42H è supportato se FORCE LBA è zero
0000:7c80 a0 41 7c
mov
al,ds:0x7c41
0000:7c83 84 c0
test
al,al
0000:7c85
75 05
supportato: esegui da 7C8C
jne
LBA
pag. 8/12
and
74 37
supportato: esegui da 7CC3
LBA
H
0000:7c87 83 e1 01
0000:7c8a
0x7c8c
je
H
(prova con CHS)
cx,0x1
0x7cc3
LBA non
0000:7c8c 66 8b 4c 10
mov
ecx,[si+0x10]
0000:7c90 be 05 7c
mov
si,0x7c05
mov
[si-0x01],0x01
Disk address
packet
0000:7c93 c6 44 ff 01
0000:7c97
66 8b 1e 44 7c
mov
ebx,0x7c44
Settore
relativo allo stage2
0000:7c9c c7 04 10 00
mov
[si],0x10
0000:7ca0 c7 44 02 01 00
mov
[si+0x02],0x01
0000:7ca5 66 89 5c 08
mov
[si+0x08],ebx
0000:7ca9 c7 44 06 00 70
mov
[si+0x06],0x7000
0000:7cae 66 31 c0
xor
eax,eax
0000:7cb1 89 44 04
mov
[si+0x04],ax
0000:7cb4 66 89 44 0c
mov
[si+0x0c],eax
0000:7cb8 b4 42
mov
ah,0x42
0000:7cba cd 13
int
0x13
Chiama la
routine di interrupt 13H (AH=42H), che legge i settori dal disco in modalità LBA
0000:7cbc
72 05
supportato: continua da 7CC3
jb
H
0x7cc3
LBA non
(prova con CHS)
0000:7cbe bb 00 70
mov
bx,0x7000
0000:7cc1 eb 7d
jmp
0x7d40
mov
ah,0x8
Continua da
7D40H
Determina la geometria dell’HD (CHS)
0000:7cc3 b4 08
0000:7cc5 cd 13
int
0x13
Chiama la
routine di interrupt 13H (AH=08H), che legge la geometria CHS del disco
0000:7cc7
73 0a
jae
0x7cd3
0000:7cc9 f6 c2 80
test
dl,0x80
0000:7ccc 0f 84 f3 00
je
0x7dc3
continua da 7CD3
Tutto ok,
H
di un HD: continua da 7DC3
H
Non si tratta
(tale indirizzo si trova dentro la partition table - per un HD - infatti
viene preso in considerazione soltanto in caso di floppy disk)
0000:7cd0 e9 8d 00
jmp
0x7d60
0000:7cd3 be 05 7c
mov
si,0x7c05
0000:7cd6 c6 44 ff 00
mov
[si-0x01],0x00
0000:7cda 66 31 c0
xor
eax,eax
0000:7cdd 88 f0
mov
al,dh
0000:7cdf 40
inc
ax
0000:7ce0 66 89 44 04
mov
[si+0x04],eax
0000:7ce4 31 d2
xor
dx,dx
0000:7ce6 88 ca
mov
dl,cl
7D60H
Salva il numero di testine
pag. 9/12
Continua da
0000:7ce8 c1 e2 02
shl
dx,0x2
0000:7ceb 88 e8
mov
al,ch
0000:7ced 88 f4
mov
ah,dh
0000:7cef 40
inc
ax
0000:7cf0 89 44 08
mov
[si+0x08],ax
0000:7cf3 31 c0
xor
ax,ax
0000:7cf5 88 d0
mov
al,dl
0000:7cf7 c0 e8 02
shr
al,0x2
mov
[si],eax
0000:7cfd 66 a1 44 7c
mov
eax,ds:0x7c44
0000:7d01 66 31 d2
xor
edx,edx
0000:7d04 66 f7 34
div
[si]
Salva il numero di cilindri
Salva il numero di settori
0000:7cfa 66 89 04
Carica lo stage 2 (bottom half)
0000:7d07
88 54 0a
mov
[si+0x0a],dl
Salva il
settore iniziale
0000:7d0a 66 31 d2
xor
edx,edx
0000:7d0d 66 74 04
div
[si+0x04]
0000:7d11
88 54 0b
mov
[si+0x0b],dl
Salva la
89 44 0c
mov
[si+0x0c],ax
Salva il
testina iniziale
0000:7d14
cilindro iniziale
0000:7d17 3b 44 08
cmp
0000:7d1a 7d 3c
HD errata: continua da 7D58
jge
ax,[si+0x08]
0x7d58
Geometria
H
Calcolo CHS (BIOS geometry translation)
0000:7d1c 8a 54 0d
mov
dl,[si+0x0d]
0000:7d1f c0 e2 06
shl
dl,0x6
0000:7d22 8a 4c 0a
mov
cl,[si+0x0a]
0000:7d25 fe c1
inc
cl
0000:7d27 08 d1
or
cl,dl
0000:7d29
8a 6c 0c
mov
ch,[si+0x0c]
Settore e
parte più significativa del cilindro in CL, parte meno significativa del cilindro in CH
0000:7d2c 5a
0000:7d2d 8a 74 0b
pop
mov
dx
dh,[si+0x0b]
Testina in
DH
0000:7d30 bb 00 70
bx,0x7000
0000:7d33 8e c3
mov
es,bx
0000:7d35 31 db
xor
bx,bx
0000:7d37 b8 01 02
mov
ax,0x0201
0000:7d3a cd 13
pag. 10/12
mov
int
0x13
Chiama la
routine di interrupt 13H (AH=02H), che legge settori dal disco (CHS)
0000:7d3c 72 2a
jb
0x7d68
Errore nella
lettura dal disco: continua da 7D68H
0000:7d3e 8c c3
mov
bx,es
Copia il contenuto del buffer appena letto, in un altra zona di memoria
0000:7d40 8e 06 48 7c
mov
0000:7d44 60
pusha
0000:7d45 1e
push
ds
0000:7d46 b9 00 01
mov
cx,0x0100
0000:7d49 8e db
mov
ds,bx
0000:7d4b 31 f6
xor
si,si
0000:7d4d 31 ff
xor
di,di
0000:7d4f fc
cld
0000:7d50 f3 a5
repz movs es:[di],ds:[si]
0000:7d52 1f
pop
0000:7d53 61
popa
0000:7d54
ff 26 42 7c
dall’indirizzo contenuto in 7C42
H
jmp
es,[0x7c48]
ds
[0x7c42]
Continua
(lo stage2)
Visualizza “Geom”
0000:7d58 be 7c 7d
0000:7d5b
e8 40 00
routine che inizia da 7D9E
mov
call
si,0x7d7c
0x7d9e
Esegui la
H
0000:7d5e eb 0e
jmp
0x7d6e
mov
si,0x7d81
Continua da
7D6EH
Visualizza “Hard Disk”
0000:7d60 be 81 7d
0000:7d63
e8 38 00
routine che inizia da 7D9E
call
0x7d9e
Esegui la
H
0000:7d66 eb 06
jmp
0x7d6e
mov
si,0x7d8b
Continua da
7D6EH
Visualizza “Read”
0000:7d68 be 8b 7d
0000:7d6b
e8 30 00
routine che inizia da 7D9E
call
0x7d9e
Esegui la
H
Visualizza “ Error”
0000:7d6e be 90 7d
0000:7d71
e8 2a 00
routine che inizia da 7D9E
pag. 11/12
H
mov
call
si,0x7d90
0x7d9e
Esegui la
0000:7d74 eb fe
jmp
0x7d74
STOP !
Subroutine visualizzazione messaggio (a partire da ds:[si])
0000:7d97 bb 01 00
mov
bx,0x01
0000:7d9a b4 0e
mov
ah,0xe
0000:7d9c cd 10
int
0x10
Chiama la
routine di interrupt 10H (AH=0EH), che visualizza un carattere sullo schermo
0000:7d9e
ac
lods
al,ds:[si]
Copia il
carattere da visualizzare in AL
0000:7d9f 3c 00
cmp
al,0x00
Confronta AL
con 0
0000:7da1
75 f4
carattere non è 0 continua da 7D97
0000:7da3
jne
H
0x7d97
il
(visualizzalo)
c3
ret
all’istruzione successiva all’ultima CALL dalla quale eri provenuto
[Avanti] [Indietro] [Su] [Indice]
pag. 12/12
Se
Ritorna