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