Iniziamo la nostra analisi di un sistema operativo partendo dalla fase di avvio della macchina, nota come boot process.

La fase di avvio (Boot Process)

Quando (ri)avviamo il nostro computer, la macchina deve caricare in memoria il sistema operativo andandolo a cercare tra le periferiche di archiviazione di massa disponibili (quali floppy disk, usb key, cdrom, hard disk, ecc.).

Ma prima di poter fare questo, è necessario verificare la presenza e il corretto funzionamento di tali periferiche hardware.

E’ compito quindi del BIOS procedere a tale verifica preliminare, facendo uso di alcuni servizi predefiniti.

Come vedremo, potremo richiamare tali servizi mediante alcune istruzioni codificate in linguaggio macchina.

Il BIOS (Basic Input/Output Software) fornisce infatti un ambiente di esecuzione preliminare costituito da routine software che permettono l’accesso di base alle periferiche hardware, consentendo alla macchina di caricare ed eseguire il sistema operativo prescelto.

Le routine del BIOS sono memorizzate in un chip, e vengono caricate in memoria RAM e inizializzate a seguito dell’accensione della macchina.

Le routine di rilevamento del BIOS

In fase di avvio, il BIOS fornisce il rilevamento automatico e il controllo di base dei dispositivi essenziali del computer, come lo schermo, la tastiera e i dischi rigidi.

Dopo che il BIOS ha completato alcuni test di basso livello dell’hardware durante la fase nota come POST (Power-On Self Test), tra cui in particolare se la memoria RAM installata funziona correttamente o meno, può avviare il sistema operativo memorizzato su uno dei dispositivi di massa.

Tuttavia il BIOS non è in grado di caricare il sistema operativo da un disco fisco come se fosse un comune file, in quanto il BIOS non ha a disposizione i meccanismi offerti da un file-system.

Il BIOS deve quindi leggere gli specifici settori di dati da posizioni fisiche specifiche dei dispositivi di massa.

Quindi, il modo più semplice per il BIOS per individuare il sistema operativo è quello di caricare il primo settore di uno dei dischi impostato come periferica di avvio (es. Cilindro 0, Testa 0, Settore 0).

Tale settore è anche noto come settore di avvio e ha una dimensione totale di 512 bytes.

Poiché alcuni dei dischi installati sulla macchina potrebbero non contenere un sistema operativo (in quanto tali dischi potrebbero essere semplicemente utilizzati ai fini di archiviazione), è importante che il BIOS possa individuare correttamente il settore di avvio da eseguire.

A tal fine, il BIOS utilizza uno strategemma: verifica che gli ultimi due byte del settore selezionato come di avvio siano impostati con la sequenza esadecimale 0xaa55 (noto come magic number).

All’avvio della macchina quindi il BIOS analizza ogni dispositivo di archiviazione (ad es. unità floppy, disco rigido, unità CD, ecc.), legge il settore di avvio in memoria e indica alla CPU di iniziare a eseguire il primo settore di avvio che termina con la sequenza di bytes 0xaa55.

Boot sector di esempio

Vediamo adesso un esempio concreto di boot sector: utilizzeremo un editor esadecimale quale ad es. HxD editor per creare da zero un settore di avvio di 512 bytes che il BIOS riconosca come valido e avviabile.

I valori esadecimali che immetteremo nel nostro boot sector sono mostrati nella figura sottostante:

boot sector

Vi sono alcune caratteristiche importanti da notare:

  • i primi 3 bytes (box verde nella figura) espressi in esadecimale dai valori e9 fd ff corrispondono alla codifica in linguaggio macchina di una istruzione jmp che non esce mai (in pratica realizza un loop infinito);

  • gli ultimi 2 bytes (box rosso nella figura) corrispondono al magic number 0xaa55 che identificano il settore come boot sector valido;

  • i bytes intermedi sono costituiti tutti da zeri (espressi in esadecimale con il valore 0x00) e sono in numero tale da completare i 512 bytes necessari per avere un settore di avvio: il numero preciso di tali zeri è pari nel nostro caso a 512 – 5 = 507 (è la differenza tra 512 meno i 3 bytes iniziali e i 2 bytes finali del boot sector);

Una considerazione particolare va fatta in merito all’ordinamento dei bytes in memoria: nel caso delle CPU X86, i byte vengono ordinati in memoria secondo il modello little-endian, che memorizza prima i bytes meno significativi, seguiti da quelli più significativi.

Tale modello spiega perchè il magic number sia rappresentato nel boot sector dalla sequenza 0x55aa (come mostrato nell’immagine sopra, nel box in rosso) anzichè nella sequenza originaria 0xaa55.

In pratica, il modello di ordinamento little-endian rappresenta i singoli bytes della sequenza in ordine al contrario rispetto alle ordinarie convenzioni di numerazione cui siamo comunemente abituati.

Il boot sector che abbiamo appena creato inserendo i singoli 512 bytes all’interno di un file binario utilizzando un editor esadecimale, rappresenta un valido settore di avvio che può essere caricato ed eseguito all’interno di una virtual machine (nel caso di una macchina fisica, potremmo utilizzare un comando Linux come cat o dd per scriverlo all’interno del primo settore di un floppy disk o anche di un hard disk di avvio e accendere la macchina…)

Come creare un Boot sector di esempio

Vedremo adesso come creare passo passo un settore di avvio utilizzando un editor esadecimale come HxD (disponibile per il download al link: https://mh-nexus.de/en/hxd/ ).

Per prima cosa avviamo il nostro editor esadecimale:

editor HxD

Dal menu File selezioniamo ‘New’ (oppure digitiamo la sequenza di tasti ‘Ctrl + N’):

new file

Quindi salviamo il file con il nome “boot-sector.bin”

save file

A questo punto inseriamo nel file 512 bytes costituiti da altrettanti zeri, selezionando ‘Insert bytes’ dal menu ‘Edit’:

insert bytes

insert 512 bytes

Sovrascriviamo adesso i primi tre bytes con i valori E9 FD FF corrispondenti all’istruzione di ciclo infinito tramite jmp:

insert jmp

Allo stesso modo sovrascriviamo gli ultimi due bytes con la sequenza 55 AA corrispondente al magic number che identifica il settore come di avvio:

insert magic number

Salviamo il file così modificato, e voilà, abbiamo creato il nostro settore avviabile!

Adesso non ci resta che caricarlo su una virtual machine ed eseguirlo.