Programarea Calculatoarelor 2 - Laborator 11

Să se scrie un program care afișează și modifică datele din tabela de partiții a unui disc, similar cu programul fdisk sub DOS/Windows sau UNIX.

Tabela de partiții se află în primul sector (0) al discului, începând cu deplasamentul (octetul) 0x1BE si conține 4 intrări a câte 16 octeți. Un sector are 0x200 (512) octeti. Cei doi octeți rămași la sfârșitul sectorului sunt ocupați de "semnătura" convențională 0x55 0xAA. Conținutul unei intrări din tabela este următorul:
- un octet (boot flag) care indică o partiție activă (0x80) sau nu (0), deci dacă se poate lansa spre încărcare sistemul de operare
- 3 octeți care indică poziția primului sector fizic al partiției în format HSC (head, sector, cylinder) descris ulterior
- un octet identificator pentru tipul de partiție (0 pentru partiție goală, 7 pentru NTFS, 0x83 pentru Linux, etc.)
- o altă secvență de 3 octeți în format HSC indicând poziția ultimului sector fizic al partiției
- un întreg fără semn pe 4 octeți indicând numărul logic al primului sector al partiției (numărul de sectoare care-l preced pe disc)
- un întreg fără semn pe 4 octeți indicând dimensiunea partiției în sectoare

Scrieți un program care acceptă următoarele comenzi (câte o literă mică):
d șterge o partiție: cere un număr între 1 și 4, pune identificatorul și toți octeții din intrarea respectivă pe zero.
m afișează meniul de comenzi
p afișează tabela de partiții (un tabel cu câte un rând pentru fiecare partiție existentă). Verificati consistenta intre informatia exprimata in sectoare fizice si logice.
q iese din program, ignoră modificările făcute
w iese din program, scrie modificările pe disc

Fizic, discul e compus din mai multe platane (discuri subtiri individuale) dispuse cilindric pe o axa, in plane paralele, cu informatie inscrisa pe ambele parti. Fiecare suprafata de platan are un cap de citire propriu care se poate deplasa radial. Suprafata e astfel impartita in piste, fiecare avand pe circumferinta mai multe sectoare.
Un sector fizic e identificat pe rand, in ordine ierarhica de:
- numarul cilindrului C (totalitatea pistelor cu aceeasi pozitie radiala de pe toate suprafetele platanelor).
- numarul capului de citire H (identifica o suprafata de platan, si prin aceasta o pista in cadrul cilindrului)
- numarul sectorului S in cadrul pistei.

Formatul HSC conține
- în primul octet, numărul capului de citire (numerotat de la zero, cel mult 255)
- în cei 6 biți inferiori ai octetului al doilea, numărul sectorului în cadrul unei piste (numerotat de la 1, cel mult 63)
- în octetul al treilea, și biții 7 și 6 din octetul al doilea (considerați ca biți superiori, de rang 9 și 8), numărul cilindrului de pe disc (începând cu 0, cel mult 1023).
(Se constată că formatul HSC e limitat la 24 de biți, deci discuri de cca 8GB. Dincolo de această limită se folosește doar numărul logic de sector în cadrul discului; pentru simplificare nu vom trata acest caz.)

Convențional, fiecare partiție e aliniată de regulă la un cilindru nou (începe la sectorul 1 al capului 0 de pe acel cilindru). Excepție face începutul discului, unde e rezervata prima pistă (C=0, H=0) al carei prim sector contine tabela de partiții.

Nefiind permis accesul direct la disc, programul va lucra in loc de sectorul 0 cu fișierul de 512 octeti mbr.bin pe care il copiati in catalogul curent.
În realitate, programul fdisk afla din hardware informațiile despre geometria discului (număr de cilindri, capete, sectoare). Pentru problema dată, considerăm C=528, H=64, S=63, valori consistente cu structura dată în fișierul de test.

Indicatii
Optional, implementati si comanda
n creează o partiție nouă: solicită un număr între 1 și 4; un cilindru de început de partiție; un cilindru de sfârșit de partiție; un tip (identificator) de partiție. Partiția nu trebuie să se suprapună peste cele existente.

Pentru manipularea intrărilor din tabela de partiții lucrati direct cu un tablou de octeți, din care obtineti un camp prin conversia la tipul dorit a unui pointer la deplasamentul (offsetul) respectiv. Pentru întregii pe dimensiune fixă în octeți, soluția portabilă în standardul C99 este folosirea tipurilor definite în stdint.h, în acest caz tipul uint32_t.

Definiti macro-uri care extrag dintr-un ansamblu HSC valorile individuale ale celor 3 campuri, folosind operatori pe biti.

O alternativă elegantă e definirea unui tip structură care reprezintă o intrare din tabela de partiții, eventual cu câmpuri pe biți pentru formatul HSC. Atentie! Nu avem insa garantia ca alinierea aleasa de compilator pentru structura definita (inclusiv ordonarea bitilor de la semnificativ la nesemnificativ) corespunde cu formatul specificat. În C99 putem verifica cu macro-ul offsetof din stddef.h care utilizat sub forma offsetof(struct s, f) dă o constantă întreagă care indică deplasamentul câmpului f în cadrul tipului struct s. Același rezultat se obtine cu expresia (char *)&x.f - (char *)&x dacă x are tipul struct s. Totusi, solutia ramane mai putin portabila decat cea folosind accesul direct la octeti.


Marius Minea
Last modified: Wed Nov 26 07:23:19 EET 2003