Il disco a basso livello




Negli anni ottanta un giovane signore di nome Peter Norton sorprese i suoi
amici recuperando un file cancellato, e questa piccola utility che prese il
nome di unerase lo rese famoso nel mondo della programmazione.
In questo tutorial vedremo come è organizzato il file system del DOS, vedremo
come esso salva e cancella i file e impareremo ad usare alcune routine messe
a disposizione dal sistema operativo.


Tracce e settori

Un hard-disk è costituito da un certo numero di dischi "impilati" uno sull'altro
a cui si accede per leggere e scrivere tramite un pettine di testine:

                 O     I-----------
        -------------------       |
                 O     I-----------
        -------------------   <==>|
                 O     I-----------   
        -------------------       |
                 O     I-----------
        -------------------       |
          /      O     I-----------
        /               \
      disco               \ testina

Ogni disco è costituito da 2 facce, ogni faccia da n tracce e ogni traccia da
m settori.
Il settore è l'unit… minima di informazione che puo' essere letta o scritta e
variano a seconda della capacit… del disco da 32 a 4096 byte (di solito sono
512); su ogni traccia ci sono da 4 a 32 settori e su ogni superficie da 20 a 1500
tracce.
Un settore è composto da due parti: un numero di identificazione e l'area dei
dati.


Struttura fisica di un disco

Un disco fisso è diviso in diverse aree che sono:

1.Boot Sector
2.FAT 1
3.FAT 2
4.Root directory
5.Data

Vediamoli uno a uno in dettaglio.

Boot Sector

Il boot sector è situato sul primo settore del disco e contiene vari parametri
riguardanti il disco stesso, riporto di seguito la sua struttura:

        BOOT    STRUCT
                bsJMP           db      3 dup (?)
                bsOEM           db      8 dup (?)
                bsSECTSIZE      dw      ?
                bsCLUSTSIZE     db      ?
                bsRESSECT       dw      ?
                bsFATCNT        db      ?
                bsROOTSIZE      dw      ?
                bsTOTALSECT     dw      ?
                bsMEDIA         db      ?
                bsFATSIZE       dw      ?
                bsTRACKSECT     dw      ?
                bsHEADCNT       dw      ?
                bsHIDENSECT     dd      ?
                bsHUGESECT      dd      ?
                bsDRIVENUM      db      ?
                bsRESERV        db      ?
                bsBOOTSIGN      db      ?
                bsVOLID         dd      ?
                bsVOLABEL       db      11 dup(?)
                bsFILESTYPE     db      8 dup(?)
        BOOT    ENDS

Vediamo cosa contengono:

- bsJMP: contiene un'istruzione di JMP al codice di BOOT che carica il Sistema
         Operativo dal disco. Di solito il suo valore è E9h,XX,XX

- bsOEM: è un identificativo Original Equipment Manufacturer. Non è usato dal
         dos

- bsSECTSIZE: byte per settore

- bsCLUSTER: settori per cluster

- bsRESSECT: numero di settori riservati contiene di solito il  numero di
             settori fino alla prima FAT

- bsFATCNT: numero di FAT (di solito 2).Se ne usano due per poter recuperare
            i dati nel caso una si danneggi

- bsROOTSIZE: massimo numero di voci in una directory

- bsTOTALSECT: numero di settori del drive o della partizione. Se la partizione
               è superiore a 32Mb, questo valore è 0 e il numero di settori è
               specificato nel campo bsHUGESECT

- bsMEDIA: specifica il tipo di drive FDD 3.5 1.44, FDD 3.5 2.88, CD-ROM, HD,
           ecc...

- bsFATSIZE: numero di settori di una FAT

- bsTRACKSECT: settori per traccia

- bsHEADCNT: numero di testine per la lettura/scrittura

- bsHIDENSECT: numero di settori nascosti

- bsHUGESECT: numero di settore per dischi con capacit… superiore ai 32Mb

- bsDRIVENUM: 80h se è il drive di boot, 0 altrimenti

- bsRESERV: non ancora usato (!)

- bsBOOTSIGN: 29h (??)

- bsVOLID: numero seriale del volume

- bsVOLABEL: etichetta del volume

- bsFILESTYPE: indica il tipo di  file system :FAT12 o FAT16

Questa struttura è seguita dal codice di boot che carica il S.O. e termina con
0AA55h.


FAT

Il DOS mappa lo spazio usando i Cluster non i settori e ogni cluster consiste
di un certo numero di settori consecutivi. Quando si crea un file il sistema
alloca una catena di cluster per il file, ci scrive dentro i dati e memorizza
le informazioni circa la locazione dei cluster nella File Allocation Table (FAT)
La FAT è un array con elementi di 12 o 16 bit (dipende dal numero dei cluster),
i primi 3 byte (12bit) o 4 byte (16bit) sono riservati, per quanto riguarda il
resto riporto una tabella con i valori dei possibili elementi:

        Valore                  Significato
        ----------------------------------------------------------------
        (0)000h                 Cluster libero
        (F)FF0h-(F)FF6h         Cluster riservato
        (F)FF7h                 Cluster danneggiato
        (0)002h-(F)FEFh         Cluster allocato, il numero è quello del
                                prossimo cluster nella catena
        (F)FF8h-(F)FFFh         Ultimo cluster della catena

Quando il DOS crea un nuovo file o directory memorizza l'indice del primo
cluster nella directory destinazione all'offset 1Ah e allo stesso tempo questo
è l'indice del primo elemento nella FAT. Il valore nella FAT indica il prossimo
cluster nella catena e cosi via fino all'ultimo cluster indicato con (F)FF8h-
(F)FFFh.
Vediamo un esempio.
Consideriamo un file (PIPPO.EXE) situato nella root directory e supponiamo che
inizi al cluster 04h. La struttura della FAT potrebbere essere questa:

indice 00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D

Valore ID  FFF 000 000 005 006 009 00A 000 FFF 00B FFF 000 000
                       ^^^ ^^^ ^^^         ^^^
Quelli sottolineati sono i cluster del nostro file.


ROOT DIRECTORY

Qualsiasi disco ha una root directory ed eventualmente altre sotto-directory,
ogni dir è un array di record.
La root directory è memorizzata subito dopo la seconda FAT mentre le altre dir
sono trattate come normali file.
La struttura di un elemento della directory è:

        DIRENTRY        STRUCT
                        deFILENAME      db      8 dup(?)
                        deFILEEXT       db      3 dup(?)
                        deATRIB         db      ?
                        deRESERV        db      0Ah dup (?)
                        deTIME          dw      ?
                        deDATE          dw      ?
                        deCLUSTNUM      dw      ?
                        deFILESIZE      dd      ?
        DIRENTRY        ENDS

Vediamo il significato di ogni campo:
- deFILENAME: Contiene il nome del file. Il primo carattere pu• avere un
              significato particolare:

              Valore    Significato
              ------------------------------------------------------------------
              0         L'elemento non è mai stato usato
              05h       Significa che il primo carattere del nome è 0E5h (ASCII)
              02Eh      Se il resto di questo campo sono spazi (20h) allora il
                        campo deCLUSTNUM contiene il primo cluster della
                        directory. Se anche il secondo valore è 02Eh e gli altri
                        sono spazi, il campo deCLUSTNUM contiene il primo
                        cluster della directory padre, oppure 0 se è la ROOT dir
              0E5h      Questo file o directory è stato cancellato (il resto del
                        nome rimane uguale)

- deFILEEXT: 3 caratteri che contengono l'estensione del file.

- deATRIB: Attributi del file:

                7  6  5  4  3  2  1  0  bits
                      A  D  V  S  H  R
                      |  |  |  |  |  |_ 1 = Read only
                      |  |  |  |  |____ 1 = Hidden
                      |  |  |  |_______ 1 = System
                      |  |  |__________ 1 = Volume label
                      |  |_____________ 1 = Subdirectory
                      |________________ 1 = New or modified

- deRESERV: Riservato (!)

- deTIME: L'ora in cui il file è stato creato o modificato l'ultima volta.
          Il formato è il seguente:
           15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
           H  H  H  H  H  M  M  M  M  M  M  S  S  S  S  S

- deDATE: Data in cui il file è stato creato o modificato l'ultima volta.
          Il formato è il seguente:
           15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
           Y  Y  Y  Y  Y  M  M  M  M  M  M  D  D  D  D  D

- deCLUSTNUM: Cluster iniziale della directory o del file.

- deFILESIZE: dimensione del file in bytes


Per ora non mi vengono in mente esempi significativi da mostrarvi, ci sono 
vari interrupt che servono per creare file, leggerli, scrivere settori ecc..
quindi lascio a voi il compito di scrivere qualcosa....


** [email protected] **