Cum se configurează smartphone-uri și PC-uri. Portal informativ
  • Acasă
  • Windows Phone
  • Arhitectura sistemului de fișiere FAT. Caracteristici ale sistemelor de fișiere FAT32, NTFS și exFAT

Arhitectura sistemului de fișiere FAT. Caracteristici ale sistemelor de fișiere FAT32, NTFS și exFAT

Există multe modalități de a stoca informații și programe pe hard disk. Un sistem foarte cunoscut care salvează diverse informații sub formă de fișiere, grupându-le în foldere cu o atribuire unică. Cu toate acestea, puțini oameni s-au gândit la modul în care are loc de fapt stocarea fizică a informațiilor pe un mediu.

Pentru a salva informațiile pe un mediu fizic, acestea trebuie pregătite pentru a fi utilizate într-un sistem de operare pentru computer. Sistemul de operare alocă spațiu liber pe disc pentru a salva informații. Pentru a face acest lucru, trebuie să împărțiți discul în containere mici - sectoare. Formatarea discului la nivel scăzut alocă o dimensiune specifică pentru fiecare sector. Sistemul de operare grupează aceste sectoare în clustere. Formatarea de nivel superior setează toate clusterele la aceeași dimensiune, de obicei în intervalul de la 2 la 16 sectoare. În viitor, unul sau mai multe clustere sunt alocate pentru fiecare fișier. Dimensiunea clusterului depinde de sistemul de operare, capacitatea discului și viteza de operare necesară.

Pe lângă zona pentru stocarea fișierelor pe disc, există zone necesare pentru funcționarea sistemului de operare. Aceste zone sunt pentru stocarea informațiilor de pornire și a informațiilor pentru maparea adreselor fișierelor la locații fizice de pe disc. Zona de boot este folosită pentru a porni sistemul de operare. După pornirea BIOS-ului, citește și execută zona de pornire a discului pentru a porni sistemul de operare.

Sistem de fișiere FAT

Sistemul de fișiere FAT a apărut împreună cu sistemul de operare Microsoft DOS, după care a fost îmbunătățit de mai multe ori. Are versiuni FAT12, FAT16 și FAT32. Însuși numele FAT provine de la utilizarea unui fel de bază de date de către sistemul de fișiere sub forma unui „File Allocation Table”, care conține o intrare pentru fiecare cluster de pe disc. Numerele versiunii se referă la numărul de biți utilizați în numerele de articole dintr-un tabel. Prin urmare, sistemul de fișiere are o limită pentru dimensiunea discului acceptată. În 1987, nu suporta un disc mai mare de 32 MB. Odată cu apariția Windows 95, a apărut o nouă versiune a sistemului de fișiere FAT32 cu suport teoretic pentru unități de până la 2 TB. Probleme constante cu suportarea discurilor mari apar datorita cardinalitatii fixe, limitate de numarul de biti folositi in determinarea pozitiei clusterului. De exemplu, versiunea FAT16 nu acceptă mai mult de 2 clustere 16 sau 65536. Numărul de sectoare dintr-un cluster este, de asemenea, limitat.

O altă problemă cu unitățile mari a fost incapacitatea de a utiliza spațiul imens alocat fișierelor mici. Datorită numărului limitat de clustere, dimensiunea acestora a crescut pentru a acoperi întreaga capacitate a discului. Acest lucru are ca rezultat utilizarea ineficientă a spațiului de stocare pentru majoritatea fișierelor care nu sunt un multiplu al mărimii clusterului. De exemplu, FAT32 alocă clustere de 16 KB pentru partițiile de disc care variază de la 16 GB la 32 GB. Pentru a stoca un fișier de 20 KB, veți avea nevoie de două clustere de 16 KB, care vor ocupa 32 KB pe disc. Fișierele de 1 KB ocupă 16 KB de spațiu pe disc. Astfel, în medie, 30-40% din dimensiunea capacității discului este irosită pentru stocarea fișierelor mici. Partiționarea unui disc în partiții mici poate reduce dimensiunea clusterului, dar în practică nu este utilizat pentru discuri cu o capacitate mai mare de 200 GB.

Fragmentarea fișierelor nu este, de asemenea, o problemă minoră în sistemul de fișiere. Deoarece pot fi necesare mai multe clustere pentru a găzdui un fișier și este posibil să nu fie secvenţial din punct de vedere fizic, timpul necesar pentru citire încetinește programele. Prin urmare, există o nevoie constantă de.

Sistem de fișiere NTFS

La începutul anilor 1990, Microsoft a început să dezvolte software complet nou conceput pentru medii care consumă mai multe resurse decât utilizatorii casnici obișnuiți. Pentru nevoile de afaceri și industrie, resursele oferite de sistemele de operare Windows bazate pe DOS nu mai sunt suficiente. Microsoft a încheiat un parteneriat cu IBM pentru a dezvolta OS / 2 cu sistemul de fișiere High Performance File System (HPFS). Dezvoltarea corporativă nu a avut succes și, în curând, fiecare companie a urmat din nou drumul său. Microsoft a dezvoltat diverse versiuni ale sistemului de operare Windows NT care se bazează pe Windows 2000 și Windows XP. Fiecare dintre ele folosește propria versiune a sistemului de fișiere NTFS, care continuă să evolueze.

NTFS (New Technology File System) este sistemul de fișiere standard pentru sistemele de operare bazate pe Windows NT. A fost conceput pentru a înlocui FAT. NTFS este mai flexibil decât FAT. Zonele sale de sistem stochează în mare parte fișiere, mai degrabă decât structuri fixe, cum ar fi în FAT, ceea ce le permite să fie modificate, extinse sau relocate în timpul utilizării. Un exemplu simplu este Master File Table (MFT). MFT este un fel de bază de date cu diverse informații despre fișierele de pe disc. Fișierele mici (1 KB sau mai puțin) pot fi stocate direct în MFT. Pentru fișierele mari, NTFS alocă clustere, dar spre deosebire de FAT, dimensiunea clusterului nu depășește de obicei 4 KB, iar metoda de compresie încorporată elimină problemele cu spațiul neutilizat alocat fișierelor. De asemenea, puteți utiliza NTFS.

Sistemul de fișiere NTFS este proiectat pentru un mediu multiutilizator și are mecanisme încorporate pentru protejarea și diferențierea drepturilor de acces. De exemplu, sistemele de operare Windows 2000 și Windows XP (cu excepția „Home Edition”) vă permit să setați permisiuni de acces la fișiere individuale și să le criptați. Cu toate acestea, nivelul ridicat de securitate face dificilă utilizarea computerului pentru utilizatorii obișnuiți. Fiți extrem de atenți când setați parolele și permisiunile pentru fișiere pentru a evita pierderea datelor importante.

Salutari!

Indiferent de mediul de stocare – fie că este vorba de un hard disk, SSD sau flash (MicroSD, microSDXC, USB-Flash Drive etc.), toți au nevoie de un sistem de fișiere pentru a putea scrie și citi date de pe ele.

Există o serie de sisteme de fișiere, dar în acest articol ne vom uita la cele mai populare și, în consecință, utilizate.

Informațiile furnizate vor fi foarte utile în situațiile în care trebuie să formatați un hard disk (unitate SSD) sau una dintre partițiile sale, o unitate flash USB etc.

Sistem de fișiere FAT16, FAT32 - istoric și caracteristici

Să începem cu sistemul de fișiere FAT16(se mai numește și simplu GRAS) - a fost creat în primul rând pentru sistemul de operare MS DOS, iar suportul său a fost disponibil în Windows 95 și Windows 98. Dimensiunea maximă a unui fișier a fost limitată la 2 gigaocteți. Dimensiunea maximă a partiției poate fi exact aceeași.

Dominația FAT16 nu a durat mult; în curând a fost înlocuită cu sistemul de fișiere FAT32 - a fost standard pentru Windows 95 și Windows 98, deși din motive de compatibilitate, așa cum am menționat mai sus, aceste sisteme de operare au suportat și FAT16.

În FAT32, dimensiunea maximă a fișierului era deja de 4 gigaocteți. Acestea. numărul de fișiere poate fi oricare, dar dimensiunea oricăruia dintre ele nu poate depăși 4 gigaocteți. Și dimensiunea maximă a partiției ar putea fi teoretică de 8 Terabytes, dar în Windows era limitată artificial. De exemplu, în Windows 98, dimensiunea partiției nu poate fi mai mare de 137 de gigaocteți.

S-ar putea să vă întrebați de ce, după atâția ani, puteți formata unități flash și hard disk-uri mici în acest sistem de fișiere. Răspunsul la această întrebare este mai jos.

  • Compatibilitate: FAT32 este încă acceptat pe scară largă de sistemele de operare majore: Windows, MacOS, Linux, diverse dispozitive autonome (set-top box-uri, playere MP3, telefoane, smartphone-uri etc.) și sisteme încorporate.
  • Restrictii: Dacă încercați să scrieți un fișier mai mare de 4 gigaocteți, atunci nu puteți face acest lucru și va apărea o eroare. Există soluții la această problemă.

    Există și limitări în ceea ce privește dimensiunea partiției - deși teoretic FAT32 acceptă medii de stocare de până la 8 Terabytes, în Windows XP (și mai nou) nu vei putea formata un disc sau o partiție mai mare de 32 GB în FAT32. Această limitare a fost introdusă de Microsoft pentru a menține performanța optimă atunci când lucrați cu acest sistem de fișiere.

  • astăzi acest sistem de fișiere este folosit cu succes pe unități flash și dispozitive de stocare pentru a asigura compatibilitatea maximă cu cea mai largă clasă de dispozitive.

    Un alt avantaj este absența scrierii / citirii redundante a „datelor tehnice” în procesul de interacțiune cu acest sistem de fișiere. Aceasta este, fără îndoială, o binecuvântare pentru discurile Flash, pentru care resursa de citire/scriere a celulelor de memorie este limitată.

Sistem de fișiere NTFS - descriere, aplicație și proprietăți cheie

Sistemul de fișiere NTFS astăzi este relevantă și omniprezentă. Debutând pentru prima dată în Windows XP, acesta continuă să fie utilizat în toate versiunile moderne ale sistemului de operare de la Microsoft, inclusiv în cel mai recent Windows 10.

Dezvoltatorii săi au făcut tot posibilul, dotând acest sistem de fișiere cu multe caracteristici care au fost dictate de realitățile moderne. De exemplu, datorită înregistrării informațiilor tehnice ale tuturor operațiunilor efectuate cu fișierele, a fost posibilă creșterea semnificativă a fiabilității siguranței datelor în cazul unei întreruperi bruște a curentului media.

De asemenea, în NTFS, a fost adăugată și capacitatea de a seta drepturile la fișiere și foldere, ceea ce crește semnificativ securitatea generală atunci când lucrați în Windows. Nu uitați de posibilitatea de a crea copii umbră ale fișierelor și datelor în timpul funcționării sistemului, care este utilizat în mod activ de sistemul de operare Windows, pentru a asigura performanțe ridicate la copierea de rezervă a datelor, criptare și doar funcționarea regulată a sistemului de operare .

Desigur, aceasta nu este o listă completă a ceea ce oferă sistemul modern de fișiere NTFS.

După cum am menționat mai sus, acest sistem de fișiere este standard pentru Windows XP și sistemele de operare ulterioare de la Microsoft. În timpul instalării sistemului de operare, nici măcar nu veți putea alege sistemul de fișiere - hard disk-ul sau SSD-ul vor fi formatate strict în NTFS.

Datorită complicației semnificative a principiilor sistemului de fișiere NTFS și a unor probleme de licențiere, are suport foarte limitat de la alte sisteme de operare și dispozitive.

De exemplu, sistemul de operare MacOS poate citi date numai de pe mediile pe care este utilizat NTFS, dar nu mai poate scrie date pe medii cu acest sistem de fișiere.

Situația este mai bună pe Linux. Deși în mod nativ Linux poate citi date numai de pe medii NTFS, unele distribuții finale Linux adaugă și suport pentru scrierea pe discuri NTFS.

În ceea ce privește dispozitivele de sine stătătoare, consolele de jocuri (Sony PlayStation, Xbox 360), etc., în majoritatea cazurilor NTFS nu este acceptat de acestea.

  • Compatibilitate: Complet acceptat în toate versiunile moderne ale sistemului de operare de la Microsoft. Pe Mac (MacOS), doar citirea este acceptată, iar pe Linux, citirea și scrierea sunt acceptate și pe unele distribuții finale. În ceea ce privește alte dispozitive, în majoritatea cazurilor nu este acceptat deloc.
  • Restrictii: Nu există restricții privind numărul și dimensiunea fișierelor și folderelor.
  • Domeniul optim de aplicare: Sistemul de fișiere a fost creat pentru a fi folosit pentru hard disk-uri (și mai târziu SSD-uri), în principal în mediul Windows.

Sistemul de fișiere ExFat - ce este, pentru ce a fost creat

ExFat(numit si FAT64) Este un sistem de fișiere care a debutat în 2006, creat pentru unități flash. În timpul dezvoltării sale, tot ce este mai bun de la FAT32 a fost luat și limitările sale inerente au fost eliminate. ExFat nu are nicio limitare cu privire la dimensiunea maximă a fișierului care poate fi scris pe medii cu un anumit sistem de fișiere.

A fost îmbunătățită și situația cu eliminarea numărului excesiv de operațiuni tehnice de citire/scriere pentru a asigura viteza maximă a operațiunilor de bază cu fișiere cu un impact minim asupra celulelor de memorie, pentru a preveni și a întârzia pe cât posibil uzura acestora. .

Dacă vorbim despre compatibilitate, atunci situația cu aceasta este mult mai bună în comparație cu același NTFS. MacOS are suport complet pentru operațiuni de citire/scriere, iar suportul Linux este disponibil, cu condiția să instalați mai multe pachete din depozit.

În ceea ce privește dispozitivele externe, situația cu suportul ExFat se îmbunătățește, dar este cu siguranță imposibil de garantat suport pe toate dispozitivele.

  • Compatibilitate: Are suport complet pe Windows începând cu Windows XP, MacOS și Linux OS (poate fi necesar să instalați un pachet de asistență din depozit).

    Este posibil ca dispozitivele autonome mai vechi (playere MP3, camere foto etc.) să nu fie acceptate.

  • Restrictii: Acest sistem de fișiere nu are nicio restricție atât cu privire la dimensiunea maximă a fișierului, cât și la numărul acestora.
  • Domeniul optim de aplicare: Orice unități flash și dispozitive de stocare (MicroSD, microSDXC, unitate flash USB etc.), a căror dimensiune este mai mare de 4 gigaocteți. O unitate flash cu acest sistem de fișiere va demonstra performanță de mare viteză și va funcționa mai mult decât dacă folosește NTFS.

Rezumat scurt

Pentru a rezuma cele de mai sus, se dovedește că sistemul de fișiere NTFS ar trebui utilizat pentru unitățile hard (HDD) și SSD care sunt instalate în interiorul computerului și ExFat pentru unitățile flash externe.
Și FAT32 este optim pentru unitățile flash mici (până la 4 Gigaocteți), precum și pentru unitățile flash care sunt folosite în dispozitive vechi și nu înțeleg ExFat.

Asta e tot! Ne vedem în conținut nou! Pentru a nu le rata - merită să vă abonați!

Să analizăm tipurile de sistem de fișiere pentru o unitate flash, care este mai bună. Un utilizator mi-a trimis o fotografie cu eroarea „Fișierul este prea mare pentru sistemul de fișiere țintă” și a decis să scrie un articol în ce cazuri ar trebui să folosești sistemele FAT32, NTFS și exFAT. A mutat un fișier mai mare de 4 GB pe un stick de 8 GB. Cert este că sistemul FAT32 nu poate procesa informații de peste 4 GB, dacă unitatea dvs. flash are un volum de 32 GB și sistemul său de fișiere este FAT32, atunci nu puteți scrie un fișier de peste 4 GB pe acesta. Să aruncăm o privire la toate cele trei sisteme de fișiere din Windows, să ne uităm la avantajele și dezavantajele lor.

FAT32

Vechiul mod de sistem de fișiere, care este de obicei folosit la cumpărarea unei unități flash USB dintr-un magazin, iar motivul pentru aceasta este compatibilitatea. Compatibilitatea este că FAT32 poate fi folosit pe orice computer MAC, Windows, Linux, vechi. Cea mai mare limitare este că are o limită de dimensiune a fișierelor de 4 GB, care astăzi are probleme cu formate precum video 4k, Blu-ray. Pe scurt, dacă aveți de gând să lucrați cu fișiere care au o dimensiune mai mică de 4 GB și unitatea flash este utilizată pe diferite computere cu sisteme de operare diferite, atunci sistemul de fișiere FAT32 este foarte potrivit.

exFAT

Sistem de fișiere actualizat creat de Microsoft pentru a înlocui FAT32. A început cu Windows Vista SP1 și are o dimensiune maximă a fișierului de 16 exaocteți (EB), care este 1 EB = 10 18 octeți. Compatibil cu Mac OS și Windows, este un sistem foarte bun pentru schimbul de fișiere mari.

Minusuri:

  • Nu are nici un fel de funcționalitate de logare în care toate modificările aduse fișierelor de pe disc să fie înregistrate înainte de a fi efectuate efectiv.
  • Nu este acceptat de Time Machine la Apple. Pe scurt, nu veți putea face copii de rezervă de la Apple folosind software-ul Time Machine.
  • O structură foarte complexă care necesită mai multă putere de calcul.

Pro:

  • Suprascrie același sector de mai puține ori, ceea ce este important pentru unitățile flash, prelungind durata de viață a celulelor de memorie. După cum știți, unitățile flash au un număr N de rescrieri, apoi eșuează.
  • Limită de dimensiune mare a fișierului de 16 exaocteți.
  • Dimensiunea clusterului este de 32 de megaocteți.
  • Alocarea îmbunătățită a spațiului liber, care reduce defragmentarea discului.

NTFS

Cel mai nou sistem de fișiere creat de Microsoft este structura modernă de astăzi pentru aproape orice hard disk intern modern, unitate flash sau disc ssd. NTFS este o nouă tehnologie de sistem de fișiere. Windows poate fi instalat numai pe NTFS. Este valoarea implicită pentru discurile sistemului de operare datorită versatilității sale. Are toate tehnologiile Microsoft: înregistrare, nicio limită de dimensiune a fișierelor, suport pentru compresia fișierelor, nume lungi, control acces la fișiere pentru administratorii de server și multe altele. Acasă, aceasta este cea mai bună opțiune pentru utilizarea acestui sistem pe discuri și unități flash. Există o captură, când introduceți o unitate flash USB în Mac OS, puteți copia informații de pe o unitate flash USB, dar fără nicio modificare.

Ieșire:

Pentru stick-uri USB, trebuie să utilizați exFAT, dacă vă aflați în mod constant în mediul Mac OS, Windows, mutați unitatea flash USB de la un sistem de operare la altul. Dacă utilizați doar Windows, atunci NTSF este o soluție excelentă.

VLADIMIR MESHKOV

Arhitectura sistemului de fișiere FAT

Caracteristicile generale ale sistemului de fișiere FAT. Structura partiției FAT

Sistemul de fișiere FAT (File Allocation Table) a fost dezvoltat de Bill Gates și Mark MacDonald în 1977 și a fost utilizat inițial în sistemul de operare 86-DOS. Pentru a obține portabilitatea programelor din sistemul de operare CP / M la 86-DOS, restricțiile adoptate anterior privind numele fișierelor au fost păstrate în acesta. Mai târziu, 86-DOS a fost achiziționat de Microsoft și a devenit baza pentru MS-DOS 1.0, lansat în august 1981. FAT a fost proiectat să funcționeze cu dischete cu o dimensiune mai mică de 1 MB și nu a acceptat inițial hard disk-uri.

Structura partiției FAT este prezentată în figură.

În sistemul de fișiere FAT, spațiul pe disc al unei partiții logice este împărțit în două zone - zona de sistem și zona de date (vezi Figura 1). Zona de sistem este creată și inițializată la formatare și, ulterior, actualizată pe măsură ce structura fișierului este manipulată. Zona de sistem a sistemelor de fișiere FAT constă din următoarele componente:

  • înregistrarea de pornire (BR);
  • zona de rezerva;
  • tabele de alocare a fișierelor;
  • zona directorului rădăcină (nu există în FAT32).

Zona de date a unui disc logic conține fișiere și directoare subordonate rădăcinii și este împărțită în secțiuni de aceeași dimensiune - clustere. Un cluster poate consta din unul sau mai multe sectoare situate secvenţial pe disc. Numărul de sectoare dintr-un cluster trebuie să fie un multiplu de 2N și poate lua valori de la 1 la 64. Mărimea clusterului depinde de tipul de sistem de fișiere utilizat și de dimensiunea discului logic.

Scopul, structura și tipurile tabelului de alocare a fișierelor

FAT și-a primit numele din tabelul de alocare a fișierelor cu același nume - Tabelul de alocare a fișierelor, FAT. Tabelul de alocare a fișierelor stochează informații despre clusterele unui disc logic. Fiecare cluster corespunde unui element al tabelului FAT, care conține informații despre dacă acest cluster este liber sau ocupat de date de fișier. Dacă clusterul este ocupat de un fișier, atunci adresa clusterului care conține următoarea parte a fișierului este indicată în elementul corespunzător al tabelului de alocare a fișierelor. Numărul de grup de început ocupat de un fișier este stocat în intrarea de director care conține intrarea fișierului. Ultimul element al listei de clustere conține sfârșitul fișierului (EOF - End Of File). Primele două elemente FAT sunt rezervate.

Sistemul de fișiere FAT umple întotdeauna spațiul liber pe disc secvențial de la început până la sfârșit. Când se creează un fișier nou sau se mărește unul existent, acesta caută primul cluster gratuit din tabelul de alocare a fișierelor. Dacă în timpul funcționării unele fișiere au fost șterse, iar altele și-au schimbat dimensiunea, atunci clusterele goale rezultate vor fi împrăștiate pe disc. Dacă clusterele care conțin datele fișierului nu sunt aranjate într-un rând, atunci fișierul este fragmentat.

Există următoarele tipuri de FAT - FAT12, FAT16, FAT32. Numele tipului FAT derivă din dimensiunea elementului: FAT12 este de 12 biți (1,5 octeți), FAT16 este de 16 biți (2 octeți), FAT32 este de 32 de biți (4 octeți). În FAT32, cei mai importanți patru biți sunt rezervați și ignorați de sistemul de operare.

Directorul rădăcină

Tabelele de alocare a fișierelor sunt urmate de directorul rădăcină. Fiecare fișier și subdirector din directorul rădăcină are o intrare de director de 32 de octeți care conține numele fișierului, atributele (arhivate, ascunse, de sistem și numai pentru citire), data și ora creării (sau ultima modificare), precum și alte informații. Pentru sistemele de fișiere FAT12 și FAT16, poziția directorului rădăcină pe partiție și dimensiunea acestuia sunt fixate în mod rigid. În FAT32, directorul rădăcină poate fi localizat oriunde în zona de date a partiției și poate avea o dimensiune arbitrară.

Formate de nume de fișiere

Una dintre caracteristicile versiunilor timpurii ale FAT (FAT12 și FAT16) este utilizarea numelor scurte de fișiere. Numele scurt este format din două câmpuri - un câmp de 8 octeți care conține numele propriu-zis al fișierului și un câmp de 3 octeți care conține extensia (formatul „8.3”). Dacă numele fișierului introdus de utilizator este mai scurt de 8 caractere, atunci acesta este umplut cu spații (cod 0x20); dacă extensia introdusă este mai scurtă de trei octeți, atunci este de asemenea umplută cu spații.

Structura de intrare a directorului pentru un nume scurt de fișier este prezentată în Tabelul 1.

Primul octet al numelui scurt servește ca semn că directorul este ocupat:

  • dacă primul octet este 0xE5, atunci intrarea în director este liberă și poate fi folosită la crearea unui fișier nou;
  • dacă primul octet este 0x00, atunci intrarea în director este liberă și este începutul unei zone de director curate (nu există nicio intrare după aceasta).

Tabelul 1. Structura unei intrări de director pentru un nume scurt de fișier

Părtinire

Dimensiune (octeți) Conţinut
0x00 11 Nume scurt de fișier
0x0B 1 Atributele fișierului
0x0C 1 Rezervat pentru Windows NT.
0x0D 1 Câmpul care specifică timpul creării fișierului (conține zeci de milisecunde). Câmpul este procesat numai în FAT32
0x0E 1 Ora a fost creată fișierul. Câmpul este procesat numai în FAT32
0x10 2 Data la care a fost creat fișierul. Câmpul este procesat numai în FAT32
0x12 2 Data la care fișierul a fost accesat ultima dată pentru scrierea sau citirea datelor. Câmpul este procesat numai în FAT32
0x14 2 Cuvântul de prim rang al primului număr de grup din fișier. Câmpul este procesat numai în FAT32
0x16 2 Ora ultimei scrieri în fișier
0x18 2 Data ultimei scrieri în fișier
0x1A 2 Cuvântul cel mai puțin semnificativ din numărul primului grup al fișierului
0x1C 4 Dimensiunea fișierului în octeți

Sunt impuse o serie de restricții privind utilizarea caracterelor ASCII într-un nume scurt:

  • nu puteți folosi caractere cu coduri mai mici de 0x20 (cu excepția codului 0x05 din primul octet al unui nume scurt);
  • nu puteți folosi simboluri cu codurile 0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x5B, 0x5C, 0x7C;
  • nu puteți utiliza un caracter spațiu (0x20) în primul octet al numelui.

Sistemele de fișiere FAT32 și VFAT (FAT virtual, extensie FAT16) acceptă nume lungi de fișiere (LFN). Pentru a stoca numele lung, sunt folosite elementele de director adiacente elementului principal. Numele fișierului nu este scris în caractere ASCII, ci în Unicode. O bucată de până la 13 caractere Unicode poate fi stocată într-o singură intrare de catalog. Porțiunea neutilizată a ultimului fragment este umplută cu coduri 0xFFFF. Structura de intrare a directorului pentru un nume lung de fișier este prezentată în Tabelul 2.

Tabelul 2. Structura unei intrări de director pentru un nume lung de fișier

Părtinire Dimensiune (octeți) Conţinut
0x00 1 Numărul fragmentului
0x01 10 Caracterele de nume de fișier Unicode 1-5
0x0B 1 Atributele fișierului
0x0C 1 Octet de steaguri
0x0D 1 Suma de control a numelui scurt
0x0E 12 Caracterele 6-11 ale numelui fișierului Unicode
0x1A 2 Primul număr de grup (complet cu zerouri)
0x1C 4 Caracterele 12-13 ale numelui fișierului Unicode

Sectorul de boot

Primul sector al unui disc logic FAT conține un sector de boot și un bloc de parametri BIOS. Secțiunea inițială a acestui bloc este identică pentru toate tipurile de FAT (tabelul 3). Diferențele în structura sectoarelor de boot pentru diferite tipuri de FAT încep la offset 0x24. Pentru FAT12 și FAT16, structura este prezentată în tabelul 4, pentru FAT32 - în tabelul 5.

Tabelul 3. Secțiunea inițială a sectorului de boot

Părtinire Dimensiune, octeți Descriere
0x00 3 Salt necondiționat (jmp) la codul de pornire
0x03 8 ID producator
0x0B 2 Octeți de sector (512)
0x0D 1 Numărul de sectoare dintr-un cluster
0x0E 2 Numărul de sectoare de rezervă din zona de rezervă a partiției, incepand de la primul sector al partitiei
0x10 1 Număr de tabele (copii) FAT
0x11 2 Pentru FAT12 / FAT16, numărul de descriptori de fișiere de 32 de octeți în directorul rădăcină; pentru FAT32 acest câmp are valoarea 0
0x13 2 Numărul total de sectoare din partiție; dacă acest câmp conține 0, atunci numărul de sectoare este stabilit de câmpul la offset 0x20
0x15 1 Tipul media. Pentru hard disk, valoarea este 0xF8; pentru dischetă (2 fețe, 18 sectoare pe pistă) - 0xF0
0x16 2 Pentru FAT12 / FAT16 acest câmp conține numărul de sectoare, ocupat de o copie a FAT; pentru FAT32 acest câmp are valoarea 0
0x18 2 Numărul de sectoare pe pistă (pentru întrerupere 0x13)
0x1A 2 Număr de suprafețe de lucru (pentru întrerupere 0x13)
0x1C 4 Numărul de sectoare ascunse înainte de partiție
0x20 4 Numărul total de sectoare din partiție. Câmpul este utilizat dacă secțiunea peste 65535 de sectoare, în caz contrar câmpul conține 0.

Tabelul 4. Structura sectorului de boot FAT12 / FAT16

Părtinire Dimensiune, octeți Descriere 0x24 1 Întrerupeți numărul unității 0x13 0x25 1 0x26 1 Indicator de înregistrare de pornire extinsă (0x29) 0x27 4 Numărul discului logic 0x2B 11 Etichetă disc 0x36 8 Un șir de text cu o abreviere pentru tipul de sistem de fișiere

Tabelul 5. Structura sectorului de boot FAT32

Dimensiune, octet Descriere 4 Numărul de sectoare ocupate de o copie a FAT 2 Număr FAT activ 2 Numărul versiunii FAT32: octet înalt - numărul versiunii,junior - număr de revizuire. Valoarea utilizată în prezent este 0: 0 4 Numărul clusterului pentru primul cluster al directorului rădăcină 2 Numărul de sector al structurii FSINFO în zona de rezervă a discului logic 2 Numărul de sector (în zona de rezervă a discului logic) utilizatpentru a stoca o copie de rezervă a sectorului de boot 12 Rezervat (conține 0)

Părtinire
0x24
0x28
0x2A
0x2C
0x30
0x32
0x34

Pe lângă câmpurile enumerate în tabelele 2 și 3, sectorul zero al unui disc logic trebuie să conțină codul 0x55 în octetul cu offset 0x1FE și codul 0xAA în octetul următor (offset 0x1FF). Cei doi octeți enumerați sunt un identificator de disc de pornire.

Astfel, sectorul de boot îndeplinește două funcții importante: descrie structura datelor de pe disc și, de asemenea, vă permite să porniți sistemul de operare.

Pe un disc logic cu organizare FAT32, există în plus o structură FSInfo situată în primul sector al zonei de rezervă. Această structură conține informații despre numărul de clustere libere de pe disc și numărul primului cluster liber din tabelul FAT. Formatul structurii este descris în Tabelul 6.

Tabelul 6. Structura sectorului FSInfo și a sectorului de boot de rezervă FAT32

Dimensiune, octet Descriere 4 Valoarea 0x41615252 este o semnătură care indică faptul că acest sector conține o structură FSInfo 480 Rezervat (conține 0) 4 Valoarea 0x61417272 (semnătură) 4 Conține numărul curent de clustere libere de pe disc. Dacă câmpul conține valoarea 0xFFFFFFFF, atunci numărul de clustere libere este necunoscut și trebuie calculat 4 Conține numărul de cluster de la care driverul de disc ar trebui să înceapă să caute clustere gratuite. Dacă câmpul conține valoarea 0xFFFFFFFF, atunci căutarea clusterelor gratuite ar trebui să înceapă de la clusterul numărul 2 12 Rezervat (conține 0) 4 Semnătura 0xAA550000 - semnul sfârșitului structurii FSInfo

Părtinire
0x000
0x004
0x1E4
0x1E8
0x1EC
0x1F0
0x1FC

Pentru a accesa conținutul unui fișier situat pe o partiție cu sistemul de fișiere FAT, este necesar să obțineți numărul primului cluster al fișierului. Acest număr, așa cum am stabilit deja, face parte din intrarea din directorul care conține intrarea în fișier. Primul număr de cluster corespunde unei intrări din tabelul FAT, care stochează adresa clusterului care conține următoarea parte a fișierului. Elementul FAT corespunzător ultimului cluster din lanț conține semnătura de sfârșit de fișier. Pentru FAT12 această valoare este 0xFFF, pentru FAT16 este 0xFFFF, pentru FAT32 este 0xFFFFFFFF.

Să ne uităm la implementarea software a algoritmului de citire pentru fiecare tip de FAT și să începem cu FAT16.

Toate textele sursă luate în considerare în articol sunt disponibile pe site-ul revistei.

Implementarea software a algoritmului pentru citirea unui fișier dintr-o partiție logică cu sistemul de fișiere FAT16

Să dezvoltăm un modul care citește primele N clustere ale unui fișier creat pe o partiție cu sistemul de fișiere FAT16. Parametrul N (numărul de clustere de citit) este variabil și este definit de utilizator. Numele fișierului corespunde formatului „8.3”, adică. este scurt. Modulul funcționează sub sistemul de operare Linux.

Să definim fișierele antet necesare:

#include

#include

#include

#include

#include

#include „split.h”

Fișierul antet split.h are următorul conținut:

#include

#define SHORT_NAME 13 // lungimea maximă a unui nume scurt de fișier

struct split_name (

nume U8; // Nume de fișier

U8 ext; // extensia fișierului

Int name_len, // lungimea numelui fișierului

Ext_len; // lungimea extensiei fișierului

Structura split_name are scopul de a stoca părțile constitutive ale numelui scurt de fișier (nume și extensie) și lungimile acestora.

Fișierul antet definește tipurile structurale care descriu principalele componente ale sistemului de fișiere FAT - sectorul de boot, sectorul FSInfo, structurile elementelor de director pentru nume de fișiere scurte și lungi.

Să luăm în considerare pe scurt câmpurile care sunt incluse în fiecare dintre aceste structuri.

    1. Structura sectorului de pornire struct fat_boot_sector:
      • __s8 system_id- identificator de sistem;
      • __u8 sector_size - dimensiunea sectorului în octeți;
      • __u8 cluster_size- dimensiunea clusterului pe sectoare;
      • __u16 rezervat- numărul de sectoare de rezervă din zona de rezervă a partiției;
      • __u8 grăsimi- numărul de copii FAT;
      • __u8 dir_entries- numărul de descriptori de fișiere de 32 de octeți din directorul rădăcină;
      • __u8 sectoare- numarul de sectoare pe partitie; dacă acest câmp este 0, se utilizează câmpul total_sect;
      • __u8 media- tipul de suport pe care este creat sistemul de fișiere;
      • __u16 grăsime- Mărimea grăsimii pe sectoare;
      • __u32 total_sect- dimensiunea partiției FAT în sectoare (dacă sectoarele câmpului == 0).
      • __u32 fat32_length- dimensiunea FAT32 pe sectoare;
      • __u32 cluster_rădăcină- numărul primului cluster al directorului rădăcină;
      • __u16 info_sector- numărul sectorului care conține structura FSInfo.

Următoarele câmpuri din această structură sunt utilizate numai de FAT32:

  1. Structura sectorului FSInfo struct fat_boot_fsinfo:
    • __u32 semnătură1- semnătura 0x41615252;
    • __u32 semnătură2- semnătura 0x61417272;
    • __u32 clustere_gratuite- numărul de clustere libere. Dacă câmpul conține -1, căutarea clusterelor libere trebuie începută de la clusterul numărul 2.
  2. Structura intrării de director a numelui scurt struct msdos_dir_entry:
    • __s8 nume, ext- numele și extensia fișierului;
    • __u8 attr- atribute fisierului;
    • __u8 ctime_ms- acest câmp specifică timpul de creare a fișierului până la ms (se folosește doar FAT32);
    • __u16 ctime- timpul de creare a fișierului (se folosește doar FAT32);
    • __u16 cdate- data creării fișierului (se folosește doar FAT32);
    • __u16 adate- data ultimului acces la fisier (se foloseste doar FAT32);
    • __u16 starthi- mare 16 biți din numărul primului cluster al fișierului (se folosește doar FAT32);
    • __u16 ora, data, începutul- ora și data creării fișierului, numărul primului cluster al fișierului;
    • dimensiune __u32- dimensiunea fișierului (în octeți).
  3. Structura articolului de director cu nume lung:
    • __u8 id- Numărul de articol;
    • __u8 nume0_4- caracterele 1 - 5 ale numelui;
    • __u8 attr- atribute fisierului;
    • __u8 alias_checksum- suma de control a numelui scurt;
    • __u8 nume5_10- caracterele 6 - 11 ale numelui;
    • __u8 nume11_12- caracterele 12 - 13 ale numelui.

Să continuăm revizuirea implementării software a algoritmului și să definim numele partiției pe care este creat sistemul de fișiere FAT16:

#ifndef FAT16_PART_NAME

#define FAT16_PART_NAME „/ dev / hda1”

#endif

Structuri globale:

struct fat_boot_sector fbs; // structura sectorului de boot

struct msdos_dir_entry dentry; // structura elementului de director

Variabile globale:

U16 * grăsime16; // copiați tabelul FAT16 aici

Mărimea_sectorului U16; // dimensiunea sectorului (din FAT16)

U16 dir_entries; // numărul de descriptori de 32 de octeți

// în directorul rădăcină (0 pentru FAT32)

sectoare U16; // numărul total de sectoare din secțiune

U32 fat16_size; // Dimensiunea FAT16

U32 root_size; // dimensiunea directorului rădăcină

U16 byte_per_cluster; // dimensiunea clusterului în octeți

U16 următorul_cluster; // următorul cluster din lanț

int fat;

Să începem cu funcția principală:

int main ()

Int num;

Setăm numele complet al fișierului, al cărui conținut dorim să-l citim. Permiteți-mi să vă reamintesc că lucrăm doar cu nume scurte de fișiere. Procedura de lucru cu nume lungi nu este tratată în acest articol.

U8 * full_path = "/Folder1/Folder2/text.txt";

Deschideți fișierul dispozitivului:

Hard = deschis (FAT16_PART_NAME, O_RDONLY);

Dacă (greu< 0) {

Eroare (FAT16_PART_NAME);

Ieșire (-1);

Citim primele 10 clustere ale fișierului. Citirea este efectuată de funcția fat16_read_file (). Parametrii funcției sunt numele complet al fișierului și numărul de clustere de citit. Funcția returnează numărul de clustere citite sau -1 dacă a apărut o eroare în timpul citirii:

Num = fat16_read_file (cale_completă, 10);

Dacă (num< 0) perror("fat16_read_file");

Else printf ("Citește% d clusters", num);

Închideți fișierul dispozitivului și ieșiți:

Închidere (greu);

Returnează 0;

Funcția pentru citirea clusterelor de fișiere arată astfel:

int fat16_read_file (__ u8 * full_path, int num)

Struct split_name sn; // structura pentru stocarea părților constitutive ale fișierului

U8 tmp_name_buff; // buffer pentru stocarea temporară a elementelor compuse din calea completă a fișierului

Static int i = 1;

Int n;

U8 * tmp_buff;

U16 start_cluster, următorul_cluster;

Am enumerat parametrii funcției atunci când luăm în considerare funcția principală.

Operații pregătitoare - repunerea la zero a buffer-ului tmp_name_buff și a structurii struct split_name sn:

Primul caracter dintr-o cale absolută trebuie să fie o bară oblică (/). Verificăm asta:

Citim sectorul de boot din partiție:

Dacă (read_fbs ()< 0) return -1;

Sectorul de pornire citit este acum în structura globală fat_boot_sector fbs. Să copiem din această structură dimensiunea sectorului, numărul de intrări din directorul rădăcină și numărul total de sectoare de pe partiție:

Să determinăm dimensiunea clusterului în octeți:

Byte_per_cluster = fbs.cluster_size * 512

Să afișăm informațiile din sectorul de boot:

Printf („System id -% s”, fbs.system_id);

Printf ("Dimensiunea sectorului -% d", dimensiune_sector);

Printf ("Dimensiunea cluster -% d", fbs.cluster_size);

Printf ("Rezervat -% d", fbs.reserved);

Printf („numărul FATs -% d”, fbs.fats);

Printf ("Dir intrări -% d", dir_entries);

Printf ("Sectoare -% d", sectoare);

Printf ("Media - 0x% X", fbs.media);

Printf ("lungime FAT16 -% u", fbs.fat_length);

Printf ("Total secta -% u", fbs.total_sect);

Printf ("Byte per cluster -% d", byte_per_cluster);

Calculați dimensiunea FAT16 în octeți și citiți-o:

Fat16_size = fbs.fat_length * 512;

Dacă (read_fat16 ()< 0) return -1;

Citim directorul rădăcină:

Dacă (read_root_dentry ()< 0) return -1;

Pointerul dir_entry este acum poziționat în zona de memorie care conține intrările directorului rădăcină. Dimensiunea acestei zone de memorie este egală cu dimensiunea directorului rădăcină (root_size).

Să salvăm (pentru control) conținutul directorului rădăcină într-un fișier separat:

#ifdef DEBUG

Închide (gras);

#endif

Calculăm începutul zonei de date:

Data_start = 512 * fbs.reserved + fat16_size * fbs.fats + root_size;

Cu toate intrările din directorul rădăcină la locul lor, putem ajunge la conținutul fișierului test.txt. În acest scop, vom organiza un ciclu. În corpul buclei, să analizăm numele complet al fișierului, evidențiind elementele acestuia - subdirectoare (avem două dintre ele, Folder1 și Folder2) și numele fișierului dorit (test.txt).

În timp ce (1) (

Memset (tmp_name_buff, 0, SHORT_NAME);

Memset ((void *) & sn, 0, sizeof (struct split_name));

Pentru (n = 0; n< SHORT_NAME; n++, i++) {

Dacă ((tmp_name_buff [n] == "/") || (tmp_name_buff [n] == "?")) (

I ++;

Pauză;

Tmp_name_buff [n] = "?";

Completați struct split_name sn cu informațiile corespunzătoare. Umplerea este efectuată de funcția split_name, în timp ce numele fișierului este verificat cu formatul „8.3”:

< 0) {

Printf ("nume nevalid");

Retur -1;

Pentru fiecare element al numelui complet al fișierului, definim un cluster inițial. Pentru a face acest lucru, căutați în elementele directorului (începând de la rădăcină) o intrare corespunzătoare elementului de nume complet și citiți această intrare. Funcția get_dentry () efectuează procedura de căutare:

Dacă (get_dentry (& sn)< 0) {

Printf ("Nu există un astfel de fișier!");

Retur -1;

Verificarea atributelor fișierului. Dacă este un director, citiți conținutul acestuia și continuați bucla:

Dacă (dentry.attr & 0x10) (

Dacă (read_directory (dentry.start)< 0) return -1;

Continua;

Dacă acesta este un fișier, citiți primele clustere num. Pentru control, vom salva informațiile citite într-un fișier separat:

Dacă (dentry.attr & 0x20) (

Start_cluster = dentry.start;

Tmp_buff = (__u8 *) malloc (byte_per_cluster); // conținutul cluster-ului va fi citit aici

N = deschis („clust”, O_CREAT | O_RDWR, 0600); // salvează informațiile citite în acest fișier

Dacă (n< 0) {

Eroare („deschis”);

Retur -1;

Pentru a citi grupurile de fișiere, vom organiza un ciclu:

Pentru (i = 0; i< num; i++) {

Citim conținutul clusterului în buffer-ul tmp_buff și îl salvăm într-un fișier separat:

< 0) return -1;

< 0) {

eroare („scrie”);

Închidere (n);

Retur -1;

Citim din FAT16 numărul următorului cluster ocupat de acest fișier. Dacă acesta este ultimul cluster, întrerupem bucla și revenim la funcția principală:

#ifdef DEBUG

Printf ("OK. Citit");

Printf ("următorul cluster al fișierului - 0x% X ..", următorul_cluster);

#endif

Dacă (clusterul următor == EOF_FAT16) (

#ifdef DEBUG

Printf ("ultimul cluster.");

#endif

Gratuit (tmp_buff);

Închidere (n);

Returnează ++ i;

#ifdef DEBUG

Printf ("opriți citirea");

#endif

Întoarce i;

Citirea sectorului de boot FAT16 este efectuată de funcția read_fbs (). Rezultatul este plasat în structura globală fbs:

int read_fbs ()

Dacă (citește (hard, (__ u8 *) & fbs, sizeof (fbs))< 0) return -1;

Returnează 0;

Citirea tabelului de alocare a fișierelor din sistemul de fișiere FAT16 este efectuată de funcția read_fat16 ():

int read_fat16 ()

U64 seek = (__u64) (fbs.reserved) * 512; // offset la FAT16 de la începutul partiției

Fat16 = (void *) malloc (fat16_size);

Dacă (pread64 (hard, (__u8 *) fat16, fat16_size, seek)< 0) return -1;

Returnează 0;

Citirea directorului rădăcină este efectuată de funcția read_root_dentry ():

int read_root_dentry ()

U64 seek = (__u64) fbs.reserved * 512 + fat16_size * fbs.fats; // deplasare către directorul rădăcină de la începutul secțiunii

Root_size = 32 * dir_entries; // calculează dimensiunea directorului rădăcină

Dir_entry = (__u8 *) malloc (root_size);

Dacă (! Dir_entry) returnează -1;

Memset (dir_entry, 0, root_size);

Dacă (pread64 (hard, dir_entry, root_size, seek)< 0) return -1;

Returnează 0;

Citirea unui cluster aparținând unui fișier este efectuată de funcția read_cluster (). Parametrii de intrare ai funcției sunt numărul clusterului cluster_num și un pointer către bufferul __u8 * tmp_buff, unde ar trebui plasat rezultatul citit. Decalajul față de grupul de pe secțiune este calculat prin formula (vezi):

SEEK = DATA_START + (CLUSTER_NUM - 2) * BYTE_PER_CLUSTER,

  • CĂUTA- offset la clusterul de pe partiție
  • DATA_START- începerea zonei de date
  • CLUSTER_NUM- numărul de ordine al clusterului
  • BYTE_PER_CLUSTER- dimensiunea clusterului în octeți

int read_cluster (__ u16 cluster_num, __u8 * tmp_buff)

U64 seek = (__u64) (byte_per_cluster) * (cluster_num - 2) + data_start; // calculează offset-ul pentru cluster

< 0) return -1;

Returnează 0;

Funcția read_directory citește intrările din director (nu rădăcina) și plasează rezultatul în zona de memorie la care este setat indicatorul dir_entry:

int read_directory (__ u16 start_cluster)

Int i = 1;

U16 următorul_cluster;

Pentru (;; i ++) (

Alocam memorie pentru a stoca conținutul directorului, citim conținutul clusterului de pornire și obținem valoarea următorului cluster din tabelul FAT16:

Dacă (! Dir_entry) returnează -1;

< 0) return -1;

Următorul_cluster = fat16;

Să salvăm conținutul directorului într-un fișier separat (pentru control):

#ifdef DEBUG

Printf ("Următorul cluster - 0x% X", următorul_cluster);

Fat = deschis ("dir16", O_CREAT | O_WRONLY, 0600);

Scrie (grasime, dir_entry, root_size);

Închide (gras);

#endif

Dacă se ajunge la ultimul cluster, ieșiți din buclă, în caz contrar continuați să citiți directorul, mărind dimensiunea buffer-ului dir_entry cu încă un cluster:

Dacă (next_cluster & EOF_FAT16) se întrerupe;

Start_cluster = următorul_cluster;

Returnează 0;

Funcția get_dentry () caută în conținutul directorului un articol care se potrivește cu fișierul pe care îl căutați. Intrările pentru această funcție sunt un pointer către o struct split_name * sn care conține elementele numelui scurt al fișierului:

Int i = 0;

Bufferul global dir_entry conține o serie de intrări de director în care vom căuta o intrare de fișier (sau director). Pentru a căuta, vom organiza un ciclu. În corpul buclei, copiați intrările de director în structura globală dentry și comparați valoarea câmpurilor de nume și ext ale acestei structuri cu câmpurile corespunzătoare ale structurii struct split_name * sn. Coincidența acestor câmpuri înseamnă că am găsit intrarea fișierului solicitat în matricea elementelor de catalog:

pentru (;; i ++) (

Dacă (! (Memcmp (dentry.name, sn-> nume, sn-> name_len)) &&

! (memcmp (dentry.ext, sn-> ext, sn-> ext_len)))

Pauză;

Dacă (! Dentry.name) returnează -1;

#ifdef DEBUG

Printf ("nume -% s", dentry.name);

Printf ("pornire cluster - 0x% X", dentry.start);

Printf ("dimensiunea fișierului -% u", dentry.size);

Printf ("fișier atrib - 0x% X", dentry.attr);

#endif

Returnează 0;

Tot codul de mai sus se află în directorul FAT16, fișierul fat16.c. Pentru a obține modulul executabil, creați un Makefile cu următorul conținut:

INCDIR = / usr / src / linux / include

PHONY = curat

Fat16: fat16.o split.o

Gcc -I $ (INCDIR) $ ^ -g -o [email protected]

% .o:% .c

Gcc -I $ (INCDIR) -DDEBUG -c $ ^

Curat:

Rm -f * .o

Rm -f ./fat16

Implementarea software a algoritmului pentru citirea unui fișier dintr-o partiție logică cu sistemul de fișiere FAT12

În general, algoritmul pentru citirea unui fișier dintr-o partiție FAT12 este identic cu algoritmul pentru citirea unui fișier dintr-o partiție FAT16. Diferența constă în procedura de citire a elementelor din tabelul FAT12. Am considerat tabelul FAT16 ca o simplă matrice de elemente pe 16 biți. Următorul algoritm este propus pentru citirea elementelor tabelului FAT12:

  • înmulțiți numărul elementului cu 1,5;
  • extrageți un cuvânt de 16 biți din FAT folosind rezultatul operației anterioare ca offset;
  • dacă numărul elementului este par, efectuați operația AND pe cuvântul citit și mascați 0x0FFF. Dacă numărul este impar, mutați cuvântul citit din tabel cu 4 biți către cei mai puțin semnificativi biți.

Pe baza acestui algoritm, vom implementa funcția de citire a elementelor din tabelul FAT12:

int get_cluster (__ u16 cluster_num)

U16 caută;

Clust U16;

Calculați offset-ul în tabelul FAT12 și citiți cuvântul de 16 biți din tabel:

Căutare = (cluster_num * 3) / 2;

Memcpy ((__ u8 *) & clust, (__u8 *) (fat12 + seek), 2);

Dacă numărul de început al clusterului este un număr par, deplasăm valoarea citită din tabel cu 4 biți către cifrele inferioare, dacă este impar, o adăugăm la 0x0FFF:

Dacă (cluster_num% 2) cluster >> = 4;

Else cluster & = 0x0FFF;

Acest fragment poate fi implementat și în assembler:

"xorw %% ax, %% ax"

"de altfel 0 $, %% cx"

"jnc 1f"

„shrw $ 4, %% dx”

"jmp 2f"

„1: și w $ 0x0FFF, %% dx”

„2: movw %% dx, %% ax”

: "= a" (următorul)

: "d" (clust), "c" (cluster_num));

Revenim rezultatul:

Clust de întoarcere;

Să ne oprim puțin mai mult asupra algoritmului în sine. Să presupunem că un fișier este creat pe o partiție FAT12 care ocupă al 9-lea și al 10-lea cluster. Fiecare element FAT12 are o lungime de 12 biți. pentru că citim elemente de 16 biți din tabel, apoi offset-ul către al 9-lea element va fi de 13 octeți (9 * 1,5 = 13, renunțăm la restul), în timp ce cei mai puțin semnificativi 4 biți vor aparține celui de-al 8-lea element al FAT. Acestea trebuie aruncate, iar pentru aceasta este suficient să deplasați elementul citit cu 4 biți către cifrele inferioare, ceea ce este furnizat de algoritm. Offset-ul la al 10-lea element va fi de 15 octeți, iar cei mai semnificativi 4 biți vor aparține celui de-al 11-lea element al FAT. Pentru a le elimina, este necesar să efectuați operația AND pe al 10-lea element și masca 0x0FFF, care corespunde și algoritmului de mai sus.

Codurile sursă ale modulului de citire a fișierului din partiția FAT12 se află în directorul FAT12, fișierul fat12.c.

Implementarea software a algoritmului pentru citirea unui fișier dintr-o partiție logică cu sistemul de fișiere FAT32

Algoritmul pentru citirea unui fișier dintr-o partiție cu sistemul de fișiere FAT32 practic nu diferă de algoritmul pentru FAT16, cu excepția faptului că în FAT32 directorul rădăcină poate fi localizat oriunde pe partiție și are o dimensiune arbitrară. Prin urmare, pentru a o face mai interesantă, să complicăm sarcina - să presupunem că știm doar numărul partiției cu sistemul de fișiere FAT32. Pentru a citi informațiile din această secțiune, trebuie mai întâi să determinați coordonatele acesteia - decalajul față de secțiunea de la începutul discului. Și pentru aceasta trebuie să aveți o idee despre structura logică a hard disk-ului.

Structura logică a hard diskului

Luați în considerare structura logică a unui hard disk care respectă standardul Microsoft - "partiție principală - partiție extinsă - partiții non-DOS".

Spațiul pe hard disk poate fi organizat ca una sau mai multe partiții, iar partițiile pot conține una sau mai multe unități logice.

Hard disk-ul de la adresa fizică 0-0-1 conține Master Boot Record (MBR). Structura MBR conține următoarele elemente:

  • bootstrap non-sistem (NSB);
  • tabel de descriere a partițiilor de disc (tabel de partiții, PT). Situat în MBR la offset 0x1BE și ocupă 64 de octeți;
  • Semnătura MBR. Ultimii doi octeți ai MBR trebuie să conțină numărul 0xAA55.

Tabelul de partiții descrie locația și caracteristicile partițiilor disponibile pe hard disk. Partițiile de disc pot fi de două tipuri - primare și extinse. Numărul maxim de partiții primare este de patru. Este obligatoriu să aveți cel puțin o partiție primară pe disc. O partiție extinsă poate fi împărțită într-un număr mare de subsecțiuni - unități logice. O structură simplificată a MBR este prezentată în Tabelul 7. Tabelul de partiții este situat la sfârșitul MBR, 16 octeți sunt alocați pentru descrierea partiției din tabel.

Tabelul 7. Structura MBR

Părtinire Dimensiune, octeți 0 446 0x1BE 16 0x1CE 16 0x1DE 16 0x1EE 16 0x1FE 2

Structura intrării în tabelul de partiții este prezentată în Tabelul 8.

Tabelul 8. Structura intrării elementului tabelului de partiții

Părtinire Dimensiune, octeți Conţinut
0x00 1 Semn activ (0 - secțiunea nu este activă, 0x80 - secțiunea este activă)
0x01 1 Numărul capului discului de la care pornește partiția
0x02 2 Numărul cilindrului și numărul sectorului de la care începe secțiunea
0x04 1 Cod de tip secțiune ID sistem
0x05 1 Numărul capului discului unde se termină partiția
0x06 2 Numărul cilindrului și numărul sectorului care încheie secțiunea
0x08 4 Numărul absolut (logic) al sectorului de pornire al partiției
0x0C 4 Dimensiunea partiției (număr de sectoare)

Primul octet din elementul de secțiune este indicatorul de activitate al secțiunii (0 - inactiv, 0x80 - activ). Servește pentru a determina dacă partiția este un sistem care poate fi pornit și dacă este nevoie să pornești sistemul de operare de pe acesta la pornirea computerului. O singură secțiune poate fi activă. Indicatorul activ al partiției este urmat de coordonatele începutului partiției - trei octeți, adică numărul capului, numărul sectorului și numărul cilindrului. Numerele de cilindru și de sector sunt specificate în formatul de întrerupere Int 0x13, adică biții 0-5 conțin numărul sectorului, biții 6-7 sunt cei mai semnificativi doi biți ai numărului cilindrului de 10 biți, iar biții 8-15 sunt cei mai puțin semnificativi opt biți ai numărului cilindrului. Acesta este urmat de ID-ul sistemului, care identifică sistemul de operare pentru această partiție. Identificatorul este de un octet. În spatele identificatorului de sistem se află coordonatele sfârșitului secțiunii - trei octeți care conțin numerele capului, sectorului și, respectiv, cilindrului. Următorii patru octeți sunt numărul de sectoare dinaintea partiției, iar ultimii patru octeți sunt dimensiunea partiției în sectoare.

Astfel, un element de tabel de secțiuni poate fi descris folosind următoarea structură:

struct pt_struct (

U8 bootabil; // steag de activitate al secțiunii

U8 start_part; // coordonatele începutului secțiunii

U8 tip_parte; // identificator de sistem

U8 end_part; // coordonatele sfârșitului secțiunii

U32 sec_înainte; // numărul de sectoare înainte de secțiune

U32 sec_total; // dimensiunea partiției în sectoare (numărul de sectoare din partiție)

Elementul partiției primare indică direct către sectorul de boot al discului logic (există întotdeauna un singur disc logic în partiția primară), iar elementul partiției extinse indică o listă de discuri logice formată din structuri numite secundare. MBR (SMBR).

Fiecare disc al partiției extinse are propriul său bloc SMBR. SMBR are o structură similară cu MBR, dar nu are o înregistrare de pornire (umplută cu zerouri) și sunt folosite doar două dintre cele patru câmpuri de descriptor de partiție. Primul element al partiției indică discul logic, al doilea element indică următoarea structură SMBR din listă. Ultimul SMBR din listă conține codul de secțiune zero în al doilea element.

Să revenim la modulul de citire a unui fișier dintr-o partiție FAT32.

Fișiere antet:

#include

#include

#include

#include

#include

Semnătura MBR:

#define SEMNATURĂ 0xAA55

Fișierul dispozitivului din care vor fi citite informații despre partiții:

#define DEVICE „/ dev / hda”

Dimensiunea elementului tabelului de partiții (16 octeți):

#define PT_SIZE 0x10

Următoarea matrice de structuri stabilește corespondența dintre codul tipului de secțiune și reprezentarea sa simbolică:

struct systypes (

U8 tip_parte;

U8 * nume_parte;

struct systypes i386_sys_types = (

(0x00, „Gol”),

(0x01, „FAT12”),

(0x04, „FAT16<32M"},

(0x05, „Extins”),

(0x06, „FAT16”),

(0x0b, „Win95 FAT32”),

(0x0c, „Win95 FAT32 (LBA)”),

(0x0e, „Win95 FAT16 (LBA)”),

(0x0f, „Win95 Ext” d (LBA) „),

(0x82, „Linux swap”),

(0x83, „Linux”),

(0x85, „Linux extins”),

(0x07, „HPFS / NTFS”)

Determinați numărul de elemente din matricea i386_sys_types folosind macrocomanda PART_NUM:

#define PART_NUM (dimensiunea (i386_sys_types) / sizeof (i386_sys_types))

Să stabilim o limită pentru numărul de discuri logice:

#define MAX_PART 20

Următoarea matrice de structură va conține informații despre discurile logice de pe dispozitiv (hard disk):

struct pt_struct (

U8 bootabil;

U8 start_part;

U8 tip_parte;

U8 end_part;

U32 sec_înainte;

U32 sec_total;

) pt_t;

int greu; // descriptor de fișier al dispozitivului

U8 mbr; // numărați MBR aici

Numărul partiției pe care este creat sistemul de fișiere FAT32:

#define FAT32_PART_NUM 5

Sectorul de pornire, sectorul FSInfo și structurile de intrare în catalog (definite în fișierul ):

struct fat_boot_sector fbs;

struct fat_boot_fsinfo fsinfo;

struct msdos_dir_entry dentry;

U32 * fat32 = NULL; // copiați tabelul FAT32 aici

Mărimea_sectorului U16; // dimensiunea sectorului (din FAT32)

U16 dir_entries; // 0 pentru FAT32

sectoare U16; // numărul de sectoare pe partiție

U32 fat32_size; // Dimensiunea FAT32

U32 data_start; // începutul zonei de date

U16 byte_per_cluster; // câți octeți sunt în cluster (dimensiunea clusterului în octeți)

U32 următorul_cluster; // următorul cluster din lanț

U32 root_cluster; // ROOT cluster - cluster inițial de rădăcină

U8 * dir_entry = NULL; // pointer către intrările din director

U64 start_seek = 0; // pornind decalajul la secțiune (în octeți)

Functie principala:

int main ()

Int num = 0;

Int cluster_num = 5; // câte clustere să citiți din fișier

U8 * full_path = "/ Folder1 / Folder2 / readme"; // fișier de citit

Deschidem dispozitivul, obținem informații despre tabelul de partiții de pe dispozitiv și afișăm informații despre partiții:

Hard = deschis (DEV_NAME, O_RDONLY);

Dacă (greu< 0) {

Eroare (DEV_NAME);

Ieșire (-1);

Dacă (get_pt_info (greu)< 0) {

Eroare („get_pt_info”);

Ieșire (-1);

Show_pt_info ();

Calculăm offset-ul de pornire pentru secțiune:

Start_seek = (__u64) (pt_t.sect_before) * 512;

Citim clusterele aparținând fișierului:

Num = fat32_read_file (cale_completă, număr_cluster);

Dacă (num< 0) perror("fat32_read_file");

Else printf ("Citește% d clustere \ n", num);

Închidere (greu);

Returnează 0;

Informațiile despre tabelul de partiții sunt citite de funcția get_pt_info ():

int get_pt_info (int hard)

Int i = 0;

U64 caută;

Citim tabelul de partiții din MBR și verificăm semnătura:

Read_main_ptable (hard);

Dacă (check_sign ()< 0) {

Printf („Semnătură incorectă! \ N”);

Retur -1;

Căutăm identificatorul secțiunii extinse. Dacă există unul, calculăm offset-ul față de partiția extinsă și citim informațiile despre discurile logice:

pentru (; i< 4; i++) {

Dacă ((pt_t [i] .type_part == 0xF) || \

(pt_t [i] .type_part == 0x5) || \

(pt_t [i] .type_part == 0x0C)) (

Seek = (__u64) pt_t [i] .sect_before * 512;

Read_ext_ptable (hard, seek);

Pauză;

Returnează 0;

Funcția Read_main_ptable () pentru citirea tabelului de partiții:

void read_main_ptable (int hard)

Dacă (citește (hard, mbr, 512)< 0) {

eroare („citește”);

Închidere (greu);

Ieșire (-1);

Memset ((void *) pt_t, 0, (PT_SIZE * 4));

Memcpy ((void *) pt_t, mbr + 0x1BE, (PT_SIZE * 4));

Întoarcere;

Funcția de verificare a semnăturii check_sign ():

int check_sign ()

semnul U16 = 0;

Memcpy ((void *) & semn, (void *) (mbr + 0x1FE), 2);

#ifdef DEBUG

Printf ("Semnătura - 0x% X \ n", semn);

#endif

Dacă (semn! = SEMNATURĂ) returnează -1;

Returnează 0;

Funcția de citire a tabelului de partiții extinse:

void read_ext_ptable (int hard, __u64 seek)

Int num = 4; // începând din această poziție, matricea structurilor pt_t va fi umplută cu informații despre discuri logice

U8 smbr;

Date de intrare:

  • greu- descriptor de fișier dispozitiv;
  • căuta- offset la partiția extinsă de la începutul discului (în octeți).

Pentru a obține informații despre discurile logice, organizăm un ciclu:

Pentru (;; num ++) (

Citim SMBR situat la căutarea offset de la începutul discului:

Memset ((void *) smbr, 0, 512);

Pread64 (greu, smbr, 512, cauta);

Umplem două elemente ale tabelului pt_t, pornind de la poziția num. Primul articol va indica unitatea logică, iar al doilea va indica următoarea structură SMBR:

Memset ((void *) & pt_t, 0, PT_SIZE * 2);

Memcpy ((void *) & pt_t, smbr + 0x1BE, PT_SIZE * 2);

Facem o modificare la câmpul „Numărul sectorului de pornire” - numărarea este de la începutul discului:

Pt_t.sect_before + = (cauta / 512);

Dacă codul tipului de partiție este zero, atunci nu mai există unități logice:

Dacă (! (Pt_t.type_part)) break;

Calculați decalajul față de următorul SMBR:

Căutare = ((__u64) (pt_t.sect_before + pt_t.sect_total)) * 512;

Întoarcere;

Funcția show_pt_info () afișează informații despre unitățile logice găsite pe dispozitiv:

void show_pt_info ()

Int i = 0, n;

#ifdef DEBUG

Printf ("Numărul de partiții de pe disc -% d \ n", PART_NUM);

#endif

Pentru (; i< MAX_PART; i++) {

Dacă (! Pt_t [i] .type_part) break;

Printf ("\ nTipul secțiunii% d -", i);

Pentru (n = 0; n< PART_NUM; n++) {

Dacă (pt_t [i] .type_part == i386_sys_types [n] .part_type) (

Printf ("% s \ n", i386_sys_types [n] .part_name);

Pauză;

If (n == PART_NUM) printf ("tip necunoscut \ n");

Printf ("Semnul de pornire - 0x% X \ n", pt_t [i] .bootable);

Printf ("Sectoare în secțiune% d -% d \ n", i, pt_t [i] .sect_total);

Printf ("Sectoare înainte de secțiune% d -% d \ n \ n", i, pt_t [i] .sect_before);

Întoarcere;

Citirea clusterelor de fișiere dintr-o partiție FAT32 este efectuată de funcția fat32_read_file (). Această funcție are multe în comun cu funcția fat16_read_file (), deci consultați secțiunea 6 pentru comentarii detaliate:

int fat32_read_file (__ u8 * full_path, int num)

Struct split_name sn;

U8 tmp_name_buff;

Int i = 1, n;

U32 start_cluster, următorul_cluster;

U8 * tmp_buff;

Operațiuni pregătitoare - ștergeți tamponul, structura și verificați prima bară oblică:

Memset (tmp_name_buff, 0, SHORT_NAME);

Memset ((void *) & sn, 0, sizeof (struct split_name));

Dacă (cale_completă! = "/") Returnează -1;

Citim sectorul de boot:

Dacă (read_fbs ()< 0) return -1;

Memcpy ((void *) & sector_size, (void *) fbs.sector_size, 2);

Memcpy ((void *) & dir_entries, (void *) fbs.dir_entries, 2);

Memcpy ((void *) & sectoare, (void *) fbs.sectors, 2);

Citim structura FSInfo și afișăm semnătura conținută în ea:

Dacă (read_fs_info ()< 0) return -1;

Printf ("Semnătura1 - 0x% X \ n", fsinfo.semnatura1);

Printf ("Semnătura2 - 0x% X \ n", fsinfo.signature2);

Fat32_size = fbs.fat32_length * 512; // Dimensiunea FAT32 în octeți

Data_start = 512 * fbs.reserved + fat32_size * 2; // începutul câmpului de date

Byte_per_cluster = fbs.cluster_size * 512; // dimensiunea clusterului în octeți

Root_cluster = fbs.root_cluster; // numărul de cluster al directorului rădăcină

Citim FAT32:

Dacă (read_fat32 ()< 0) return -1;

Alocați memorie pentru intrările din director:

Dir_entry = (__u8 *) malloc (byte_per_cluster);

Dacă (! Dir_entry) returnează -1;

Citim directorul rădăcină:

Dacă (read_directory (root_cluster)< 0) return -1;

Analizăm calea completă a fișierului și împărțim fiecare element în componentele sale:

În timp ce (1) (

Memset (tmp_name_buff, 0, SHORT_NAME);

Memset ((void *) & sn, 0, sizeof (struct split_name));

Pentru (n = 0; n< SHORT_NAME; n++, i++) {

Tmp_name_buff [n] = calea_completă [i];

Dacă ((tmp_name_buff [n] == "/") || (tmp_name_buff [n] == "\ 0")) (

I ++;

Pauză;

Tmp_name_buff [n] = "\ 0";

Dacă (nume_divizat (tmp_name_buff și sn)< 0) {

Printf ("nume nevalid \ n");

Retur -1;

Dacă (get_dentry (& sn)< 0) {

Printf ("Nu există un astfel de fișier! \ N");

Retur -1;

Pentru a obține numărul de început al unui cluster în sistemul de fișiere FAT32, trebuie să utilizați cel mai semnificativ cuvânt din numărul primului cluster al fișierului - câmpul starthi al structurii dentry:

Start_cluster = (((__u32) dentry.starthi<< 16) | dentry.start);

Verificarea octetului de atribut:

Dacă (dentry.attr & 0x10) (// acesta este un director

Dacă (read_directory (start_cluster)< 0) return -1;

Continua;

Dacă (dentry.attr & 0x20) (// și acesta este un fișier

Tmp_buff = (__u8 *) malloc (byte_per_cluster);

N = deschis („clust”, O_CREAT | O_RDWR, 0600);

Dacă (n< 0) {

Eroare („deschis”);

Retur -1;

Printf ("primul cluster al fișierului - 0x% X ..", start_cluster);

Pentru (i = 0; i< num; i++) {

Memset (tmp_buff, 0, byte_per_cluster);

Dacă (read_cluster (start_cluster, tmp_buff)< 0) return -1;

Dacă (scrieți (n, tmp_buff, byte_per_cluster)< 0) {

eroare („scrie”);

Retur -1;

Dacă (clusterul următor == EOF_FAT32) (

Gratuit (tmp_buff);

Închidere (n);

Returnează ++ i;

Start_cluster = următorul_cluster;

Întoarce i;

Scopul următoarelor trei funcții este de a obține conținutul zonei de sistem, adică. sectorul de boot, structura FSInfo și tabelul FAT32:

1) funcția read_fbs () citește sectorul de boot:

int read_fbs ()

Dacă (pread64 (hard, (__u8 *) & fbs, sizeof (fbs), start_seek)< 0) return -1;

Returnează 0;

2) funcția read_fs_info () citește structura FSInfo:

int read_fs_info ()

U64 seek = (__u64) fbs.info_sector * 512 + start_seek;

Dacă (pread64 (hard, (__u8 *) & fsinfo, sizeof (fsinfo), seek)< 0) return -1;

Returnează 0;

3) funcția read_fat32 () citește tabelul FAT32:

int read_fat32 ()

U64 seek = (__u64) fbs.reserved * 512 + start_seek;

Fat32 = (void *) malloc (fat32_size);

Dacă (! Fat32) returnează -1;

Dacă (pread64 (hard, (__u8 *) fat32, fat32_size, seek)< 0) return -1;

Returnează 0;

Funcția read_cluster () citește clusterul cu numărul specificat:

int read_cluster (__ u32 cluster_num, __u8 * tmp_buff)

U64 seek = (__u64) (byte_per_cluster) * (cluster_num - 2) + data_start + start_seek;

Dacă (pread64 (hard, tmp_buff, byte_per_cluster, seek)< 0) return -1;

Returnează 0;

Citirea directoarelor (inclusiv cel rădăcină) este gestionată de funcția read_directory ():

int read_directory (__ u32 start_cluster)

Int i = 2;

U32 următorul_cluster;

Parametrii funcției - cluster de director de pornire. Citim conținutul directorului în buffer-ul global dir_entry:

Dacă (read_cluster (start_cluster, dir_entry)< 0) return -1;

Următorul_cluster = fat32;

Dacă directorul ocupă un cluster - ieșiți, dacă nu - creșteți dimensiunea memoriei și continuați să citiți:

Pentru (;; i ++) (

Start_cluster = următorul_cluster;

Dir_entry = (__u8 *) realloc (dir_entry, i * byte_per_cluster);

Dacă (! Dir_entry) returnează -1;

Dacă (read_cluster (start_cluster, (dir_entry + (i - 1) * byte_per_cluster))< 0) return -1;

Următorul_cluster = fat32;

Dacă ((următorul_cluster == EOF_FAT32) || (next_cluster == 0xFFFFFF8)) returnează 0;

Returnează 0;

Ultima funcție la care ne vom uita caută în conținutul unui director un element care se potrivește cu fișierul pe care îl căutați:

int get_dentry (struct split_name * sn)

Int i = 0;

Pointerul dir_entry este setat la o zonă de memorie care conține o matrice de intrări de director în care vom căuta un fișier (sau director). Pentru a căuta, organizăm un ciclu și punem înregistrarea găsită în structura globală de dentiză:

Pentru (;; i ++) (

Memcpy ((void *) & dentry, dir_entry + i * sizeof (dentry), sizeof (dentry));

Dacă (! (Memcmp (dentry.name, sn-> nume, sn-> name_len)) &&

! (memcmp (dentry.ext, sn-> ext, sn-> ext_len)))

Pauză;

Dacă (! Dentry.name) returnează -1;

Returnează 0;

Aceasta încheie revizuirea modulului pentru citirea unui fișier dintr-o partiție FAT32.

Codurile sursă ale modulului se află în directorul FAT32, fișierul fat32.c.

Diferențele în organizarea stocării înregistrărilor fișierelor în directoare pentru sistemele de fișiere FAT și EXT2

Câteva cuvinte despre diferențele în organizarea stocării înregistrărilor de fișiere în directoare pentru sistemele de fișiere FAT și EXT2. Structura sistemului de fișiere EXT2 a fost discutată în.

Tocmai ne-am familiarizat cu FAT - în el toate elementele catalogului au o dimensiune fixă. La crearea unui fișier, driverul sistemului de fișiere caută prima poziție neocupată și o umple cu informații despre fișier. Dacă lungimea directorului nu se încadrează într-un cluster, atunci i se alocă un alt cluster etc.

Să vedem cum stau lucrurile în EXT2.

Să presupunem că avem o partiție cu sistemul de fișiere EXT2, dimensiunea blocului este de 4096 de octeți. În această secțiune, creăm un director. Dimensiunea directorului va fi egală cu dimensiunea blocului - 4096 octeți. Sistemul de operare creează imediat două intrări în director - intrarea pentru directorul curent și intrarea pentru directorul părinte. Intrarea curentă în director va avea 12 octeți, în timp ce intrarea părinte va fi de 4084 octeți. Să creăm un fișier în acest director. După aceea, directorul va conține trei intrări - intrarea curentă în director are 12 octeți, intrarea în directorul părinte are deja 12 octeți și intrarea în fișierul creat are, după cum probabil ați ghicit, 4072 octeți. Dacă ștergem fișierul creat, lungimea intrării directorului părinte va crește din nou la 4084 de octeți.

Astfel, la crearea unui fișier, driverul sistemului de fișiere EXT2 caută în director o intrare cu lungime maximă și o împarte, făcând loc unei noi intrări. Ei bine, dacă, până la urmă, nu există suficient spațiu, încă un bloc este alocat pentru director, iar lungimea directorului devine egală cu 8192 de octeți.

Și în concluzie - o mică corecție la articolul „Arhitectura sistemului de fișiere EXT2”.

Această revizuire se referă la funcția get_i_num () pentru determinarea numărului inodului după numele fișierului. Vechea versiune a acestei funcții arăta astfel:

int get_i_num (car * nume)

Int i = 0, rec_len = 0;

Struct ext2_dir_entry_2 dent;

Pentru (; i< 700; i++) {

If (! Memcmp (dent.name, name, dent.name_len)) break;

Rec_len + = dent.rec_len;

Returnează dent.inode;

Versiune corectata:

int get_i_num (car * nume)

* Parametrul funcției - numele fișierului. Valoarea returnată este numărul inodul al fișierului.

Int rec_len = 0;

Struct ext2_dir_entry_2 dent; // această structură descrie formatul intrării directorului rădăcină:

* Buff-ul global conține o serie de intrări de director. Pentru a determina numărul de serie al inodului fișierului, trebuie să găsiți

* în această matrice, o intrare cu numele acestui fișier. Pentru a face acest lucru, vom organiza un ciclu:

Pentru (;;) (

/ * Copiați intrările de director în structura dent: * /

Memcpy ((void *) & dent, (buff + rec_len), sizeof (dent));

* Lungimea numelui fișierului egală cu zero înseamnă că am enumerat toate intrările din director

* și înregistrările cu numele fișierului nostru nu au fost găsite. Așa că este timpul să ne întoarcem:

Dacă (! Dent.name_len) returnează -1;

/ * Căutarea este efectuată prin compararea numelor de fișiere. Dacă numele se potrivesc, ieșiți din buclă: * /

If (! Memcmp (dent.name, name, strlen (name))) break;

/ * Dacă numele nu se potrivesc, treceți la următoarea intrare: * /

Rec_len + = dent.rec_len;

/ * Dacă a reușit, returnați numărul inodul al fișierului: * /

Returnează dent.inode;

Literatură:

  1. V. Kulakov. Programarea hardware: o referință specială. a 2-a ed. / - SPb .: Petru, 2003 - 848 p.
  2. A.V. Gordeev, A.Yu. Molchanov. Software de sistem / - SPb .: Peter - 2002
  3. Meshkov V. Arhitectura sistemului de fișiere ext2. - Jurnal „Administrator de sistem”, nr. 11 (12), noiembrie 2003 - 26-32 p.

In contact cu

FAT - Tabel de alocare a fișierelor - Acest termen se referă la una dintre modalitățile de organizare a sistemului de fișiere pe un disc. Acest tabel stochează informații despre fișierele de pe hard disk ca o secvență de numere care determină unde se află fiecare parte a fiecărui fișier. Cu ajutorul său, sistemul de operare află ce clustere ocupă fișierul necesar. FAT este cel mai comun sistem de fișiere și este acceptat de marea majoritate a sistemelor de operare. FAT era inițial pe 12 biți și permitea dischete și unități logice de până la 16 MB. În MS-DOS 3.0, FAT este pe 16 biți pentru a suporta unități mai mari, iar FAT pe 32 de biți este utilizat pentru unități de până la 2.047 GB.

FAT32 este un sistem de fișiere mai nou bazat pe formatul FAT și este acceptat de Windows 95 OSR2, Windows 98 și Windows Millennium Edition. FAT32 utilizează identificatori de cluster pe 32 de biți, dar își rezervă cei 4 biți superiori, astfel încât dimensiunea efectivă a identificatorului de cluster este de 28 de biți. Deoarece dimensiunea maximă a clusterelor FAT32 este de 32KB, în teorie, FAT32 poate gestiona volume de 8TB. Windows 2000 limitează dimensiunea noilor volume FAT32 la 32 GB, deși acceptă volume EAT32 existente mai mari (create cu alte sisteme de operare). Numărul mai mare de clustere acceptate de FAT32 îi permite să gestioneze discurile mai eficient decât FAT 16. FAT32 poate folosi clustere de 512 de octeți pentru volume de până la 128 MB.

Sistemul de fișiere FAT 32 din Windows 98 este utilizat ca sistem de fișiere principal. Acest sistem de operare vine cu un program special pentru conversia unui disc de la FAT 16 la FAT 32. Windows NT și Windows 2000 pot folosi, de asemenea, sistemul de fișiere FAT și, prin urmare, puteți porni computerul de pe un disc DOS și aveți acces complet la toate fișierele. . Cu toate acestea, unele dintre cele mai avansate caracteristici ale Windows NT și Windows 2000 sunt furnizate de propriul sistem de fișiere NT, ntfs. ntfs permite partiții de disc de până la 2 TB (cum ar fi FAT 32), dar are și compresie, securitate și auditare a fișierelor încorporate pentru rețea. Și în Windows 2000 este implementat suportul pentru sistemul de fișiere FAT 32. Instalarea sistemului de operare Windows NT începe pe un disc FAT, dar la sfârșitul instalării, datele de pe disc pot fi convertite în format ntfs.

Puteți face acest lucru mai târziu folosind utilitarul Convert.exe furnizat cu sistemul de operare. Partiția de disc convertită în ntfs devine inaccesibilă altor sisteme de operare. Pentru a reveni la DOS, Windows 3.1 sau Windows 9x, trebuie să ștergeți partiția ntfs și să creați o partiție FAT. Windows 2000 poate fi instalat pe un disc cu sistemul de fișiere FAT 32 și ntfs.

Capacitățile sistemelor de fișiere EAT32 sunt mult mai largi decât cele ale FAT16. Cea mai importantă caracteristică este că acceptă unități de până la 2.047 GB și funcționează cu clustere mai mici, reducând astfel semnificativ cantitatea de spațiu pe disc irosită. De exemplu, un hard disk de 2 GB în FAT16 utilizează clustere de 32 KB, în timp ce FAT32 utilizează clustere de 4 KB. Pentru a menține pe cât posibil compatibilitatea cu programele, rețelele și driverele de dispozitiv existente, FAT32 a fost implementat cu modificări minime în arhitectură, API-uri, structurile interne de date și formatul discului. Dar, deoarece dimensiunea elementelor tabelului FAT32 este acum de patru octeți, multe structuri de date interne și de pe disc, precum și API-uri, au trebuit să fie revizuite sau extinse. Anumite API-uri de pe discurile EAT32 sunt blocate pentru a preveni utilitățile de disc vechi să corupă conținutul discurilor FAT32. Majoritatea programelor nu vor fi afectate de aceste modificări. Instrumentele și driverele existente vor funcționa și pe unitățile FAT32. Cu toate acestea, driverele de dispozitiv de blocare MS-DOS (cum ar fi Aspidisk.sys) și utilitarele de disc trebuie modificate pentru a suporta FAT32. Toate utilitarele de disc furnizate de Microsoft (Format, Fdisk, Defrag și ScanDisk pentru modurile reale și protejate) sunt reproiectate pentru a suporta pe deplin FAT32. În plus, Microsoft ajută furnizorii de top de utilitare de disc și drivere de dispozitiv să își modifice produsele pentru a accepta FAT32. FAT32 este mai eficient decât FAT16 atunci când lucrați cu discuri mai mari și nu necesită partiționare în partiții de 2 GB. Windows 98 acceptă în mod necesar FAT16, deoarece acest sistem de fișiere este compatibil cu alte sisteme de operare, inclusiv cu companii terțe. În MS-DOS Real Mode și Windows 98 Safe Mode, FAT32 este semnificativ mai lent decât FAT16. Prin urmare, la pornirea programelor în modul MS DOS, este recomandabil să includeți o comandă de încărcare a Smartdrv.exe în fișierul Autoexec.bat sau PIF, care va accelera operațiunile de pe disc. Unele programe vechi concepute pentru specificația FAT16 pot raporta informații incorecte despre cantitatea de spațiu liber sau total pe disc, dacă aceasta este mai mare de 2 GB. Windows 98 oferă noi API-uri pentru MS-DOS și Win32 care vă permit să definiți corect aceste valori. Masa 1 prezintă caracteristicile comparative ale FAT16 și FAT32.

Tabelul 1. Comparația sistemelor de fișiere FAT16 și FAT32

Implementat și utilizat de majoritatea sistemelor de operare (MS-DOS, Windows 98, Windows NT, OS/2, UNIX).

Pe acest moment acceptat numai pe Windows 95 OSR2 și Windows 98.

Foarte eficient pentru unitățile logice mai mici de 256 MB.

Nu funcționează cu unități mai mici de 512 MB.

Acceptă compresia discului, cum ar fi DriveSpace.

Nu acceptă compresia discului.

Procesează maximum 65.525 clustere, a căror dimensiune depinde de dimensiunea discului logic. Deoarece dimensiunea maximă a clusterului este de 32 KB, FAT16 poate gestiona unități logice de până la 2 GB.

Capabil să lucreze cu discuri logice de până la 2.047 GB cu o dimensiune maximă a clusterului de 32 KB.

Cu cât dimensiunea discului logic este mai mare, cu atât stocarea fișierelor în sistemul FAT „16 este mai puțin eficientă, deoarece și dimensiunea clusterelor crește. Spațiul pentru fișiere este alocat pe clustere și, prin urmare, cu volumul maxim al unui logic. disc, un fișier de 10 KB va necesita 32 KB și 22 KB de spațiu pe disc va fi irosit.

Pe unitățile logice mai mici de 8 GB, clusterele sunt de 4 KB.

Lungimea maximă posibilă a fișierului în FAT32 este de 4 GB minus 2 octeți. Aplicațiile Win32 pot deschide fișiere de această lungime fără nicio prelucrare specială. Alte aplicații ar trebui să folosească întrerupere Int 21h, funcția 716C (FAT32) cu steag deschis EXTEND-SIZE (1000h).

În sistemul de fișiere FAT32, sunt alocați 4 octeți pentru fiecare cluster din tabelul de alocare a fișierelor, în timp ce în FAT16 - 2 și în FAT12 - 1.5.

Cei mai semnificativi 4 biți ai elementului de 32 de biți din tabelul FAT32 sunt rezervați și nu participă la formarea numărului clusterului. Programele care citesc direct tabelul PAT32 trebuie să mascheze acești biți și să îi protejeze împotriva modificărilor atunci când sunt scrise valori noi.

Deci, FAT32 are următoarele avantaje față de implementările anterioare ale sistemului de fișiere FAT:

    Suportă discuri de până la 2TB;

    organizează spațiul pe disc mai eficient. FAT32 folosește clustere mai mici (4KB pentru unități de până la 8GB), care pot economisi până la 10-15% spațiu pe unități mari în comparație cu FAT;

    directorul rădăcină FAT 32, ca toate celelalte directoare, este acum nelimitat, constă dintr-un lanț de clustere și poate fi localizat oriunde pe disc;

    are o fiabilitate mai mare: FAT32 este capabil să mute directorul rădăcină și să lucreze cu o copie de rezervă FAT, în plus, înregistrarea de boot pe discuri FAT32 a fost extinsă pentru a include o copie de rezervă a structurilor de date critice, ceea ce înseamnă că discurile FAT32 sunt mai puțin sensibile la apariția unor secțiuni dăunătoare separate decât volumele FAT existente;

    programele se încarcă cu 50% mai repede.

Tabelul 2. Comparația dimensiunilor clusterelor

Volumul discului

Dimensiunea clusterului în FAT16, KB

Dimensiunea clusterului în FAT32, KB

256 MB-511 MB

Nu sunt acceptate

512 MB -1023 MB

1024 MB - 2 GB

2 GB - 8 GB

Nu sunt acceptate

8 GB-16 GB

Nu sunt acceptate

16 GB-32 GB

Nu sunt acceptate

Mai mult de 32 GB

Nu sunt acceptate

Un utilitar îmbunătățit de defragmentare a discului optimizează plasarea fișierelor aplicației încărcate în momentul pornirii aplicației. Este posibil să convertiți discul în EAT32 folosind utilitarul Drive Converter (FAT32), dar după aceea se recomandă să rulați utilitarul Disk Defragmenter, altfel computerul va funcționa cu discul mai lent decât înainte. Utilizarea FAT32 face imposibilă configurarea Windows 98 și Windows NT 4.0 Alternate Boot deoarece acesta din urmă nu acceptă FAT32. FAT32 alocă spațiu pe disc mult mai economic decât versiunile anterioare ale sistemului de fișiere FAT. Acest lucru poate elibera zeci sau chiar sute de megaocteți pe discuri mari și, atunci când este combinat cu utilitarul avansat de defragmentare a discului FAT32, reduce semnificativ timpul de încărcare a aplicațiilor. Convertirea sistemului de fișiere pe hard disk în FAT32 utilizând Drive Converter (FAT32) este simplă. Pentru a face acest lucru, deschideți meniul Start, submeniul programe, Accesorii, Instrumente de sistem și selectați comanda Drive Converter (FAT32). Conversia poate afecta caracteristicile de hibernare (salvarea stării computerului pe disc) care sunt furnizate în multe computere. Sistemele în care modul de repaus este implementat prin ARM BIOS sau ACPI (Advanced Configuration and Power Interface) S4 / BIOS trebuie să accepte FAT32 - doar atunci vor funcționa corect în Windows 98.

Majoritatea producătorilor de BIOS includ protecție antivirus care monitorizează modificările la Master Boot Record (MBR). În plus, utilitățile antivirus vechi instalate ca TSR sau drivere în mod real pot detecta modificările MBR la pornirea MS-DOS. Deoarece conversia la FAT32 va modifica în mod inevitabil MBR, unele scanere de viruși pot considera în mod eronat că acesta este un semn de infecție a sistemului. Prin urmare, dacă utilitarul antivirus detectează o modificare a MBR-ului, se oferă să o „vindece”. Cel mai bine este să dezinstalați software-ul antivirus și să dezactivați protecția antivirus încorporată în BIOS înainte de a converti unitatea la FAT32. Puteți apoi să reinstalați utilitarul antivirus și să activați protecția antivirus încorporată în BIOS.

Top articole similare