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 può 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

- bsCLUSTSIZE: 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 settori 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 (ricordo che una cifra hex è 4 bit):

        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 (vedi campo deCLUSTNUM della struttura DIRENTRY nel successivo paragrafo ROOT DIRECTORY) 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
		   Nota: 2Eh è il codice del carattere punto (.)
         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

Queste sono le nozioni di base su come è organizzato il disco. Ci sono poi vari interrupt che servono per creare file, leggerli, scrivere settori ecc.. cioè alcune funzioni messe a disposizione dal DOS per accedere ai file presenti sul disco e dal BIOS per accedere a basso livello al disco.
Gli interrupt in questione sono il 13h del BIOS e il 21h del DOS e le loro principali funzioni penso ora che siate in grado di capirle leggendole su qualche technical reference. Lascio a voi quindi il compito di approfondire e di scrivere qualche programma utile...
Assembly Page di Antonio
<< Indice >>