4.1 FATFAT jest systemem plików, który powstawał razem z systemem DOS, a potem Windows. W tym czasie rozwinęły się jego kolejne wersje FAT12, FAT16, FAT32. Nie nastąpiła jednak zasadnicza zmiana struktury samego systemu tylko jego rozszerzenie do obsługi większych dysków z zachowaniem kompatybilności do poprzednich wersji. Jedyne różnice między tymi trzema rozszerzeniami zawierają się w nagłówku BPB (BIOS Parameter Block) i w rozmiarze wpisów w tablicy FAT. Całą strukturę sektorów systemu można przedstawić w blokowym schamacie:
Boot sectorNa pierwszy sektor dysku zwany sektorem rozruchowym BS (Boot Sector) składają się najważniejsze części składowe systemu FAT. Po pierwsze jest tam struktura opisująca techniczne parametry dysku i kod ładowania do pamięci systemu operacyjnego BL (Boot Loader). Jak wiadomo sektor na dysku zajmuje 512 bajtów. Pierwsza jego część zajęta jest przez blok parametrów nośnika BPB. Struktura BPB różni się nieco w zależności od wersji systemu FAT. Jej opis znajduje się w tabeli poniżej.
Przykład pierwszego sektora dla dysku 3.5 cala: Jmp START SysName db 'MSWIN4.1' BytesPerSector dw 200h SectorsPerCluster db 1 ReservedSectors dw 1 NumberFATs db 2 MaxRootEntries dw 0E0h TotalSectorNumber dw 0B40h Media db 0F0h FATSectorsNumber dw 9 SectorsPerTrack dw 12h HeadNumber db 2 HiddenSectors dd 0 TotalSectorsNumber32 dd 0 DriveNumber db 0 Reserved1 db 0 BootSignature db 29h VolumeSerial dd -1 VolumeLabel db '11111111111' FileSystemType db 'FAT12 ' START: .............. Kod i Dane ładujące system .............. dw 0AA55h Należy pamiętać o zakończeniu wartościami 0x55 pod adresem 0x1FE i 0xAA pod adresem 0x1FF. Niezależnie od wielkości sektora te wartości muszą występować dokładnie w tych miejscach. No więc pora na omówienie szczegółowe poszczególnych bloków całej struktury.
Cała powierzchnia nośnika jest podzielona na sektory, które łączone są logicznie w obszary zwane klastrami(Cluster). Klastry są najmniejszymi porcjami danych jakie mogą być rezerwowane na przechowywanie danych plików. Dane plików są zapisywane od początku klastra nr 2, wcześniejsze klastry są zajęte przez obszary RootDir+FAT+ReservedSectors. Na początek pokażę jak policzyć rozmiary w sektorach przedstawionych wyżej bloków struktury FAT. Sektory zarezerwowane (ReservedSectors)Ilość sektorów zarezerwowanych jest podana w bloku parametrów pod adresem 0x0E. Pierwszy z tych sektorów to BootSector, a ich dodatkowa ilość może oznaczać iż został tam umieszczony dodatkowy kod programu ładującego system. Tablica FAT (FAT)dla FAT12/16 FATSize = FATNumber * FATSectorNumber dla FAT32 (FATSectorNumber=0) FATSize = NumberFATs * FATSectorNumber32 RootDirRootDirSize = (32 * MaxRootEntries + BytesPerSector -1) / BytesPerSector <- pomijając resztę Struktura RootDirRootDir jest miejscem przechowującym wpisy nagłówkowe plików znajdujących się w głównym katalogu dysku. Każdy wpis w zajmuje 0x20 bajtów. Opis poszczególnych pól wpisu jest przedstawiony w tabeli.
Pierwszy bajt nazwy ma kilka wartości zarezerwowanych dla specjalnego użycia.
Należy pamiętać o tym, że dodatkowo jest lista znaków, których użycie w polu nazwy jest zabronione.
Gdy tworzymy zwykły plik to wypełniamy każde pole według wyższej tabeli bez problemu, ale gdy ma to być katalog to trzeba pamiętać o pewnych specjalnych zastrzeżeniach. Trzeba ustawić odpowiedni bit w polu atrybutów. Ustawić długość pliku na 0. Taki katalog powinien zajmować tylko jeden klaster więc klaster na który wskazuje powinien mieć ustawiony znak końca w tablicy FAT. Należy przy tym wyzerować cały obszar tego klastra. W związku z tym, że tworzymy podkatalog trzeba uzupełnić go 2 specyficznymi wpisami. Obydwa będą całe wyzerowane, tylko niektóre pola trzeba uzupełnić.
Format zapisu Daty:
Format zapisu Czasu:
File Allocation TableJest to tablica przedstawiająca, które klastry składają się na konkretne pliki. Załóżmy, że mamy pewien plik dla którego mamy określony 0x20 bajtowy wpis w RootDir. Pod adresem 0x1A i ewentualnie dodatkowo 0x14 w tym wpisie jest adres pierwszego klastra z danymi pliku. Wiadomo, że rozmiar pliku jest 3 razy większy niż pojemność klastra więc na pewno ten plik zajmuje 3 klastry. Położenie kolejnych klastrów pliku można odczytać z tablicy FAT. Tablica FAT jest podzielona na komórki o odpowiedniej wielkości. Każdej z tych komórek są przyporządkowane w kolejności wszystkie klastry danych znajdujące się tuż za katalogiem RootDir. Przykładowy plik zajmuje 3 klastry o numerach 0x2B, 0x2C, 0x29. Po złożeniu pól z wpisu w RootDir jesteśmy w stanie określić numer 0x2B pierwszego klastra natomiast numer kolejnego znajduje się właśnie w komórce 0x2B tablicy FAT, a numer kolejnego w komórce 0x2C tej tablicy.
Jest to metoda łańcuchowa w, której każda komórka ma adres następnej. Wartością kończącą łańcuch jest kod EOC (End Of Clusterchain). Są 2 typy specjalnych wpisów w komórkach FAT pierwsza to EOC, a druga to BC (Bad Cluster).
Komórki tablicy FAT16 są kolejnymi słowami tej tablicy. W FAT32 elementy tablicy mają rozmiar podwójnych słów, należy jednak dodać, że 4 najstarsze bity są zarezerwowane i przy formatowaniu powinno się je wyzerować, a podczas zmian wartości komórki zachowywać ich stan. Dla FAT12 sprawa jest dość skomplikowana bo komórka ma rozmiar 12 bitów. Przykładowy fragment tablicy FAT12.
Pierwsza komórka ma wartość 0x4DC, druga 0x2B1, trzecia 0x044, czwarta 0x000, piąta 0x3BF. Na tym przykładzie łatwo zauważyć schemat na podstawie którego można napisać algorytm czytania wartości komórki.
Określanie typu FATJak już napisałem we wcześniejszym artykule typ systemu plików nie jest opisany po przez pole o adresie 0x36 w bloku parametrów nośnika BPB. Nie wymyśliłem tego sam tylko wzorowałem się na oryginalnej dokumentacji systemu plików FAT. Więc jeżeli nie w ten sposób to jak rozpoznać typ systemu plików ?. Postaram się to teraz opisać. Pole FileSystemType w PBP może być używane przez niektóre systemu do identyfikacji typu nośnika więc powinno się umieścić tam zgodną z typem sygnaturę np. "FAT12". Jednak to pole nie musi określać w żaden sposób systemu plików wykorzystanego do przechowania danych. Systemy firmy MS nie używają tego pola do określenia typu FAT'u tylko same sprawdzają typ za pomocą prostych przeliczeń. Aby określić typ systemu FAT należy policzyć pewną specyficzną wartość którą nazwę count of clusters (COC). Na początku trzeba policzyć ilość sektorów które zajmuje RootDir: RootDirSize = (32*MaxRootEntries+BytesPerSector-1)/BytesPerSector <- zaokrąglając w dół Dla systemu plików FAT32 pole MaxRootEntries jest równe zero tak więc wartość RootDirSize też będzie zerowa. Następnie należy policzyć ilość sektorów przeznaczonych na przechowywanie danych. Wykonuje się to po przez przedstawiony algorytm: IF ( FATSectorNumber != 0 ) FATSectors = FATSectorNumber; ELSE FATSectors = FATSectorNumber32; IF ( TotalSectorNumber != 0 ) TotalSectors = TotalSectorNumber; ELSE TotalSectors = TotalSectorNumber32; DataSectors = TotalSectors - ReservedSectors - RootDirSize - NumberFATs * FATSectorNumber Teraz można już policzyć wartość COC za pomocą której można bezpośrednio określić typ systemu plików. COC = DataSectors / SectorsPerCluser <- zaokrąglając w dół Na podstawie wartości COC można określić typ po przez określenie przedziałów w jakich ma się znajdować ta wartość dla każdego z typów.
Jest to jednoznaczny i chyba najlepszy sposób określenia typu FAT dysku. Nie możliwe jest np. żeby dysk FAT16 miał więcej klastrów niż 65524.
|