VLADIMÍR MEŠKOV
Architektúra súborového systému FAT
Všeobecné charakteristiky systému súborov FAT. Štruktúra oddielov so systémom súborov FAT
Súborový systém FAT (File Allocation Table) vyvinuli Bill Gates a Mark McDonald v roku 1977 a pôvodne sa používal v operačnom systéme 86-DOS. Na dosiahnutie prenosnosti programov z operačného systému CP/M na 86-DOS boli zachované predtým akceptované obmedzenia názvov súborov. 86-DOS následne získal Microsoft a stal sa základom pre MS-DOS 1.0, vydaný v auguste 1981. FAT bol navrhnutý na prácu s disketami menšími ako 1 MB a pôvodne neposkytoval podporu pre pevné disky.
Štruktúra FAT partície je znázornená na obrázku.
V súborovom systéme FAT je diskový priestor logického oddielu rozdelený na dve oblasti - systémovú oblasť a dátovú oblasť (pozri obr. 1). Systémová oblasť sa vytvára a inicializuje počas formátovania a následne sa aktualizuje pri manipulácii so štruktúrou súboru. Systémová oblasť súborových systémov FAT pozostáva z nasledujúcich komponentov:
- zavádzací záznam (BR);
- rezervná oblasť;
- tabuľky prideľovania súborov;
- oblasť koreňového adresára (v FAT32 neexistuje).
Dátová oblasť logického disku obsahuje súbory a adresáre podriadené koreňovému a je rozdelená na časti rovnakej veľkosti - klastre. Klaster môže pozostávať z jedného alebo niekoľkých sektorov umiestnených postupne na disku. Počet sektorov v klastri musí byť násobkom 2N a môže nadobúdať hodnoty od 1 do 64. Veľkosť klastra závisí od typu použitého súborového systému a veľkosti logického disku.
Účel, štruktúra a typy alokačnej tabuľky súborov
FAT dostal svoj názov podľa rovnomennej alokačnej tabuľky súborov – File Allocation Table, FAT. Tabuľka prideľovania súborov uchováva informácie o klastroch logického disku. Každý klaster má zodpovedajúci prvok tabuľky FAT, ktorý obsahuje informácie o tom, či je klaster voľný alebo obsadený údajmi súboru. Ak je klaster obsadený súborom, potom je adresa klastra obsahujúceho ďalšiu časť súboru uvedená v príslušnom prvku alokačnej tabuľky súborov. Číslo počiatočného klastra obsadeného súborom je uložené v položke adresára, ktorá obsahuje položku súboru. Posledný prvok zoznamu klastrov obsahuje znak konca súboru (EOF – End Of File). Prvé dva prvky FAT sú vyhradené.
Súborový systém FAT vždy zapĺňa voľné miesto na disku postupne od začiatku do konca. Pri vytváraní nového súboru alebo zvyšovaní existujúceho súboru hľadá úplne prvý voľný klaster v tabuľke prideľovania súborov. Ak boli počas prevádzky niektoré súbory odstránené a iné zmenili veľkosť, výsledné prázdne zhluky budú rozptýlené po disku. Ak klastre obsahujúce údaje súboru nie sú umiestnené v rade, súbor sa fragmentuje.
Existujú nasledujúce typy FAT – FAT12, FAT16, FAT32. Názvy typov FAT sú odvodené od veľkosti prvku: prvok FAT12 má veľkosť 12 bitov (1,5 bajtov), FAT16 - 16 bitov (2 bajty), FAT32 - 32 bitov (4 bajty). V systéme FAT32 sú štyri najvýznamnejšie bity vyhradené a počas prevádzky operačného systému sa ignorujú.
Koreňový adresár
Po alokačných tabuľkách súborov nasleduje koreňový adresár. Každý súbor a podadresár v koreňovom adresári má 32-bajtovú položku adresára, ktorá obsahuje názov súboru, jeho atribúty (archivovaný, skrytý, systémový a len na čítanie) a dátum a čas vytvorenia (alebo poslednej úpravy), ako ako aj ďalšie informácie. Pre súborové systémy FAT12 a FAT16 je pozícia koreňového adresára na oddiele a jeho veľkosť pevne zafixovaná. V systéme FAT32 môže byť koreňový adresár umiestnený kdekoľvek v dátovej oblasti oddielu a môže mať akúkoľvek veľkosť.
Formáty názvov súborov
Jednou z charakteristík starších verzií FAT (FAT12 a FAT16) je použitie krátkych názvov súborov. Krátky názov pozostáva z dvoch polí – 8-bajtového poľa obsahujúceho skutočný názov súboru a 3-bajtového poľa obsahujúceho príponu (formát „8.3“). Ak je názov súboru zadaný používateľom kratší ako 8 znakov, potom je doplnený medzerami (kód 0x20); ak je zadaná prípona kratšia ako tri bajty, doplní sa aj medzerami.
Štruktúra prvkov adresára pre krátky názov súboru je uvedená v tabuľke 1.
Prvý bajt krátkeho názvu slúži ako indikátor obsadenosti adresára:
- ak je prvý bajt 0xE5, potom je vstup do adresára voľný a možno ho použiť pri vytváraní nového súboru;
- ak je prvý bajt 0x00, potom je položka adresára voľná a je začiatkom čistej oblasti adresára (za ňou nie sú žiadne povolené položky).
Tabuľka 1. Štruktúra prvkov adresára pre krátky názov súboru
Zaujatosť |
Veľkosť (bajty) | Obsah |
0x00 | 11 | Krátky názov súboru |
0x0B | 1 | Atribúty súboru |
0x0C | 1 | Vyhradené pre Windows NT. |
0x0D | 1 | Pole určujúce čas vytvorenia súboru (obsahuje desiatky milisekúnd). Pole je spracované iba vo FAT32 |
0x0E | 1 | Čas vytvorenia súboru. Pole je spracované iba vo FAT32 |
0x10 | 2 | Dátum vytvorenia súboru. Pole je spracované iba vo FAT32 |
0x12 | 2 | Dátum posledného prístupu k súboru na zapisovanie alebo čítanie údajov. Pole je spracované iba vo FAT32 |
0x14 | 2 | Najvýznamnejšie slovo prvého čísla klastra súboru. Pole je spracované iba vo FAT32 |
0x16 | 2 | Čas poslednej operácie zápisu do súboru |
0x18 | 2 | Dátum poslednej operácie zápisu do súboru |
0x1A | 2 | Nízke slovo prvého čísla klastra súboru |
0x1C | 4 | Veľkosť súboru v bajtoch |
Existuje niekoľko obmedzení na používanie znakov ASCII v krátkom názve:
- nemôžete použiť znaky s kódmi menšími ako 0x20 (okrem kódu 0x05 v prvom byte krátkeho názvu);
- nemôžete použiť znaky s kódmi 0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x5B, 0x5C, 0x7C,;
- V prvom bajte názvu nemôžete použiť znak medzery (0x20).
Systémy súborov FAT32 a VFAT (virtuálny FAT, prípona FAT16) zahŕňajú podporu pre dlhé názvy súborov (LFN). Na uloženie dlhého názvu sa používajú prvky adresára susediace s hlavným prvkom. Názov súboru sa nezapisuje znakmi ASCII, ale Unicode. Do jednej položky adresára môžete uložiť fragment až 13 znakov Unicode. Nepoužitá časť posledného fragmentu je vyplnená kódmi 0xFFFF. Štruktúra prvkov adresára pre dlhý názov súboru je uvedená v tabuľke 2.
Tabuľka 2. Štruktúra prvkov adresára pre dlhý názov súboru
Zaujatosť | Veľkosť (bajty) | Obsah |
0x00 | 1 | Číslo fragmentu |
0x01 | 10 | Znaky 1-5 názvu súboru v Unicode |
0x0B | 1 | Atribúty súboru |
0x0C | 1 | Príznaky bajt |
0x0D | 1 | Kontrolný súčet krátkeho mena |
0x0E | 12 | Znaky 6-11 názvu súboru v Unicode |
0x1A | 2 | Číslo prvého klastra (vyplneného nulami) |
0x1C | 4 | Znaky 12-13 názvu súboru v Unicode |
Boot sektor
Prvý sektor logického disku so systémom FAT obsahuje zavádzací sektor a blok parametrov systému BIOS. Počiatočná časť tohto bloku je identická pre všetky typy FAT (tabuľka 3). Rozdiely v štruktúre zavádzacích sektorov pre rôzne typy FAT začínajú pri offsete 0x24. Pre FAT12 a FAT16 je štruktúra uvedená v tabuľke 4, pre FAT32 - v tabuľke 5.
Tabuľka 3. Úvodná časť zavádzacieho sektora
Zaujatosť | Veľkosť, bajty | Popis |
0x00 | 3 | Bezpodmienečný skok (jmp) na zavádzací kód |
0x03 | 8 | ID výrobcu |
0x0B | 2 | Počet bajtov v sektore (512) |
0x0D | 1 | Počet sektorov v klastri |
0x0E | 2 | Počet náhradných sektorov v náhradnej oblasti oddielu, počnúc prvým sektorom oddielu |
0x10 | 1 | Počet tabuliek (kópií) FAT |
0x11 | 2 | Pre FAT12/FAT16 - počet 32-bajtových deskriptorov súborov v koreňovom adresári; pre FAT32 má toto pole hodnotu 0 |
0x13 | 2 | Celkový počet sektorov v oddiele; ak toto pole obsahuje 0, potom je počet sektorov špecifikovaný poľom s ofsetom 0x20 |
0x15 | 1 | Typ média. Pre pevný disk je hodnota 0xF8; pre disketu (2 strany, 18 sektorov na stopu) – 0xF0 |
0x16 | 2 | Pre FAT12/FAT16 toto pole obsahuje počet sektorov obsadené jednou kópiou FAT; pre FAT32 má toto pole hodnotu 0 |
0x18 | 2 | Počet sektorov na stopu (pre prerušenie 0x13) |
0x1A | 2 | Počet pracovných plôch (pre prerušenie 0x13) |
0x1C | 4 | Počet skrytých sektorov pred oddielom |
0x20 | 4 | Celkový počet sektorov v oblasti. Pole sa používa, ak je sekcia viac ako 65535 sektorov, inak pole obsahuje 0. |
Tabuľka 4. Štruktúra zavádzacieho sektora FAT12/FAT16
Zaujatosť Veľkosť, bajt Popis 0x24 1 Číslo jednotky pre prerušenie 0x13 0x25 1 0x26 1 Príznak rozšíreného spúšťacieho záznamu (0x29) 0x27 4 Číslo logického disku 0x2B 11 Štítok disku 0x36 8 Textový reťazec so skratkou typu súborového systému
Tabuľka 5. Štruktúra zavádzacieho sektora FAT32
Veľkosť, bajt Popis 4 Počet sektorov obsadených jednou kópiou FAT 2 Aktívne číslo FAT 2 Číslo verzie FAT32: vysoký bajt - číslo verzie,junior – číslo revízie. Aktuálne je to 0:0 4 Číslo klastra pre prvý klaster koreňového adresára 2 Číslo sektora štruktúry FSINFO v rezervnej oblasti logického disku 2 Použité číslo sektora (v náhradnej oblasti logického disku).na uloženie záložnej kópie zavádzacieho sektora 12 Rezervované (obsahuje 0)
Zaujatosť |
0x24 |
0x28 |
0x2A |
0x2С |
0x30 |
0x32 |
0x34 |
Okrem 2. a 3. poľa uvedených v tabuľkách musí nultý sektor logického disku obsahovať kód 0x55 v byte na offset 0x1FE a kód 0xAA v nasledujúcom byte (offset 0x1FF). Uvedené dva bajty sú znakom zavádzacieho disku.
Zavádzací sektor teda plní dve dôležité funkcie: popisuje štruktúru údajov na disku a tiež umožňuje spustenie operačného systému.
Logický disk s organizáciou FAT32 navyše obsahuje štruktúru FSInfo umiestnenú v prvom sektore rezervnej oblasti. Táto štruktúra obsahuje informácie o počte voľných klastrov na disku a počte prvého voľného klastra v tabuľke FAT. Formát štruktúry je opísaný v tabuľke 6.
Tabuľka 6. Štruktúra sektora FSInfo a zavádzacieho sektora zálohy FAT32
Veľkosť, bajt Popis 4 Hodnota 0x41615252 je podpis, ktorý označuje, že tento sektor obsahuje štruktúru FSInfo 480 Rezervované (obsahuje 0) 4 Hodnota 0x61417272 (podpis) 4 Obsahuje aktuálny počet voľných klastrov na disku. Ak pole obsahuje hodnotu 0xFFFFFFFF, potom je počet voľných klastrov neznámy a musí sa vypočítať 4 Obsahuje číslo klastra, od ktorého by mal ovládač disku začať hľadať voľné klastre. Ak pole obsahuje hodnotu 0xFFFFFFFF, vyhľadávanie voľných klastrov by malo začínať klastrom číslo 2 12 Rezervované (obsahuje 0) 4 Podpis 0xAA550000 – znak konca štruktúry FSInfo
Zaujatosť |
0x000 |
0x004 |
0x1E4 |
0x1E8 |
0x1EC |
0x1F0 |
0x1FC |
Ak chcete získať prístup k obsahu súboru umiestneného na oddiele so systémom súborov FAT, musíte získať číslo prvého klastra súboru. Toto číslo, ako sme už zistili, je súčasťou položky adresára obsahujúcej položku súboru. Prvé číslo klastra zodpovedá prvku tabuľky FAT, v ktorom je uložená adresa klastra obsahujúceho ďalšiu časť súboru. Element FAT zodpovedajúci poslednému klastru v reťazci obsahuje podpis konca súboru. Pre FAT12 je táto hodnota 0xFFF, pre FAT16 – 0xFFFF, pre FAT32 – 0xFFFFFFFF.
Pozrime sa na softvérovú implementáciu čítacieho algoritmu pre každý typ FAT a začnime s FAT16.
Všetky zdrojové texty diskutované v článku sú dostupné na stránke časopisu.
Softvérová implementácia algoritmu na čítanie súboru z logického oddielu so súborovým systémom FAT16
Poďme vyvinúť modul, ktorý načíta prvých N klastrov súboru vytvoreného na partícii so súborovým systémom FAT16. Parameter N (počet klastrov na čítanie) je premenná hodnota a je určená používateľom. Názov súboru zodpovedá formátu „8.3“, t.j. je krátky. Modul pracuje pod OS Linux.
Definujme potrebné hlavičkové súbory:
#include
#include
#include
#include
#include
#include "split.h"
Hlavičkový súbor split.h má nasledujúci obsah:
#include
#define SHORT_NAME 13 // maximálna dĺžka krátkeho názvu súboru
struct split_name(
meno U8; // názov súboru
U8 ext; // rozšírenie súboru
Int name_len, // dĺžka názvu súboru
Ext_len; // dĺžka prípony súboru
Štruktúra split_name je navrhnutá na uloženie komponentov krátkeho názvu súboru (názov a prípona) a ich dĺžok.
Hlavičkový súbor definuje štrukturálne typy, ktoré popisujú hlavné komponenty systému súborov FAT – boot sektor, FSInfo sektor, štruktúry adresárových prvkov pre krátke a dlhé názvy súborov.
Pozrime sa stručne na polia, ktoré sú zahrnuté v každej z týchto štruktúr.
- Štruktúra zavádzacieho sektora struct fat_boot_sector:
- __s8 system_id– systémový identifikátor;
- __u8 sektor_veľkosť – veľkosť sektora v bajtoch;
- __u8 veľkosť_klastra– veľkosť klastra v sektoroch;
- __u16 rezervované- počet náhradných sektorov v rezervnej oblasti oddielu;
- __u8 tukov– počet kópií FAT;
- __u8 dir_entries– počet 32-bajtových deskriptorov súborov v koreňovom adresári;
- __u8 sektorov– počet sektorov na oddiele; ak je toto pole 0, použije sa pole total_sect;
- __u8 médiá– typ média, na ktorom bol vytvorený súborový systém;
- __u16 tučná_dĺžka– veľkosť FAT v sektoroch;
- __u32 total_sect– veľkosť oddielu FAT v sektoroch (ak pole sektory == 0).
- __u32 fat32_length– veľkosť FAT32 v sektoroch;
- __u32 root_cluster– číslo prvého klastra koreňového adresára;
- __u16 info_sektor– číslo sektora obsahujúceho štruktúru FSInfo.
Nasledujúce polia tejto štruktúry používa iba FAT32:
- Sektorová štruktúra FSInfo struct fat_boot_fsinfo:
- __u32 podpis1– podpis 0x41615252;
- __u32 podpis2– podpis 0x61417272;
- __u32 free_clusters– počet voľných zhlukov. Ak pole obsahuje -1, vyhľadávanie voľných klastrov musí začínať klastrom číslo 2.
- Skrátený názov štruktúry prvku adresára msdos_dir_entry:
- __s8 meno, ext– názov a prípona súboru;
- __u8 attr– atribúty súboru;
- __u8 ctime_ms– toto pole určuje čas vytvorenia súboru na ms (používa sa iba FAT32);
- __u16 ctime– čas vytvorenia súboru (používa sa iba FAT32);
- __u16 dátum– dátum vytvorenia súboru (používa sa iba FAT32);
- __u16 dátum– dátum posledného prístupu k súboru (používa sa iba FAT32);
- __u16 štarthi– najvýznamnejších 16 bitov prvého čísla klastra súboru (používa sa iba FAT32);
- __u16 čas, dátum, začiatok– čas a dátum vytvorenia súboru, číslo prvého klastra súboru;
- Veľkosť __u32– veľkosť súboru (v bajtoch).
- Štruktúra prvkov adresára s dlhým názvom:
- __u8 id– číslo prvku;
- __u8 meno0_4– znaky 1 – 5 mena;
- __u8 attr– atribúty súboru;
- __u8 alias_checksum– kontrolný súčet krátkeho názvu;
- __u8 meno5_10– symboly 6 – 11 názvu;
- __u8 meno11_12– symboly 12 – 13 názvu.
Poďme ďalej zvážiť softvérovú implementáciu algoritmu a určiť názov oddielu, na ktorom bol vytvorený súborový systém FAT16:
#ifndef FAT16_PART_NAME
#define FAT16_PART_NAME "/dev/hda1"
#koniec Ak
Globálne štruktúry:
struct fat_boot_sector fbs; // štruktúra boot sektora
struct msdos_dir_entry dentry; // štruktúra prvkov adresára
Globálne premenné:
U16 *tuk16; // tu skopírujte tabuľku FAT16
U16 sektor_veľkosť; // veľkosť sektora (z FAT16)
U16 dir_entries; // počet 32-bajtových deskriptorov
// v koreňovom adresári (0 pre FAT32)
sektory U16; // celkový počet sektorov v oddiele
U32 fat16_veľkosť; // Veľkosť FAT16
U32 root_size; // veľkosť koreňového adresára
U16 byte_per_cluster; // veľkosť klastra v bajtoch
U16 ďalší_klaster; // ďalší klaster v reťazci
int tuk;
Začnime s hlavnou funkciou:
int main()
Int num;
Zadáme celý názov súboru, ktorého obsah chceme čítať. Pripomínam, že pracujeme len s krátkymi názvami súborov. O postupe práce s dlhými názvami sa v tomto článku nehovorí.
U8 *úplná_cesta = "/Priečinok1/Priečinok2/text.txt";
Otvorte súbor zariadenia:
Hard = open(FAT16_PART_NAME, O_RDONLY);
Ak (tvrdé< 0) {
Chyba(FAT16_PART_NAME);
Exit(-1);
Čítame prvých 10 zhlukov súboru. Čítanie vykonáva funkcia fat16_read_file(). Parametre funkcie sú úplný názov súboru a počet klastrov na čítanie. Funkcia vráti počet prečítaných klastrov alebo -1, ak sa pri čítaní vyskytla chyba:
Num = fat16_read_file(úplná_cesta, 10);
Ak(č< 0) perror("fat16_read_file");
Else printf("Prečítať %d klastre ", num);
Zatvorte súbor zariadenia a ukončite:
Zavrieť (tvrdo);
Návrat 0;
Funkcia na čítanie klastrov súborov má nasledujúci tvar:
int fat16_read_file(__u8 *úplná_cesta, int num)
Struct split_name sn; // štruktúra na ukladanie komponentov súboru
U8 tmp_name_buff; // vyrovnávacia pamäť na dočasné uloženie komponentov celej cesty k súboru
Statické int i = 1;
Int n;
U8 *tmp_buff;
U16 start_cluster, next_cluster;
Parametre funkcie sme uviedli pri zvažovaní hlavnej funkcie.
Prípravné operácie - resetujte vyrovnávaciu pamäť tmp_name_buff a štruktúru split_name sn:
Prvý znak v absolútnej ceste k súboru musí byť lomka (/). Skontrolujeme toto:
Prečítajte si zavádzací sektor z oddielu:
If(read_fbs()< 0) return -1;
Čítací zavádzací sektor sa teraz nachádza v globálnej štruktúre struct fat_boot_sector fbs. Z tejto štruktúry skopírujeme veľkosť sektora, počet záznamov v koreňovom adresári a celkový počet sektorov na oddiele:
Poďme určiť veľkosť klastra v bajtoch:
Byte_per_cluster = fbs.cluster_size * 512
Zobrazme informácie nachádzajúce sa v zavádzacom sektore:
Printf("ID systému - %s ", fbs.id_systému);
Printf("Veľkosť sektora - %d ", veľkosť_sektora);
Printf("Veľkosť klastra - %d ", fbs.veľkosť_klastra);
Printf("Rezervované - %d ", fbs.rezervované);
Printf("číslo FAT - %d ",fbs.fats);
Printf("Položky adresára - %d ", položky_adresára);
Printf("Sektory - %d ", sektory);
Printf("Media - 0x%X ", fbs.media);
Printf("dĺžka FAT16 - %u ", fbs.fat_length);
Printf("Total sek - %u ", fbs.total_sect);
Printf("Bajt na klaster - %d ", byte_na_klaster);
Vypočítame veľkosť FAT16 v bajtoch a prečítame:
Fat16_size = fbs.fat_length * 512;
If(read_fat16()< 0) return -1;
Čítanie koreňového adresára:
If(read_root_dentry()< 0) return -1;
Ukazovateľ dir_entry je teraz umiestnený na pamäťovom mieste, ktoré obsahuje položky koreňového adresára. Veľkosť tejto oblasti pamäte sa rovná veľkosti koreňového adresára (veľkosť_korena).
Uložme (pre kontrolu) obsah koreňového adresára do samostatného súboru:
#ifdef DEBUG
Close(tuk);
#koniec Ak
Vypočítame začiatok oblasti údajov:
Data_start = 512 * fbs.reserved + fat16_size * fbs.fats + root_size;
Ak máme všetky položky v koreňovom adresári, môžeme sa dostať k obsahu súboru test.txt. Za týmto účelom organizujeme cyklus. V tele cyklu rozoberieme celý názov súboru, pričom zvýrazníme jeho prvky – podadresáre (máme dva z nich, Folder1 a Folder2) a názov súboru, ktorý hľadáme (test.txt).
Kým (1) (
Memset(tmp_name_buff, 0, SHORT_NAME);
Memset((void *)&sn, 0, sizeof(struct split_name));
For(n = 0; n< SHORT_NAME; n++, i++) {
If((tmp_name_buff[n] == "/") || (tmp_name_buff[n] == "?")) (
I++;
Prestávka;
Tmp_name_buff[n] = "?";
Štruktúru struct split_name sn naplníme príslušnými informáciami. Funkcia split_name vykoná vyplnenie a skontroluje, či je názov súboru v súlade s formátom „8.3“:
< 0) {
Printf("neplatné meno");
Návrat -1;
Pre každý prvok úplného názvu súboru definujeme počiatočný klaster. Aby sme to dosiahli, hľadáme v prvkoch adresára (začínajúc od koreňového adresára) položku zodpovedajúcu prvku s úplným názvom a prečítame si túto položku. Vyhľadávaciu procedúru vykonáva funkcia get_dentry():
If(get_dentry(&sn)< 0) {
Printf("Žiadny takýto súbor!");
Návrat -1;
Kontrola atribútov súboru. Ak ide o adresár, prečítajte si jeho obsah a pokračujte v slučke:
If(dentry.attr & 0x10) (
If(read_directory(dentry.start)< 0) return -1;
Ďalej;
Ak ide o súbor, čítame prvé num klastre. Pre kontrolu uložíme prečítané informácie do samostatného súboru:
If(dentry.attr & 0x20) (
Start_cluster = dentry.start;
Tmp_buff = (__u8 *)malloc (byte_per_cluster); // tu sa prečíta obsah klastra
N = open("clust", O_CREAT|O_RDWR, 0600); // uložte prečítané informácie do tohto súboru
Ak(n< 0) {
Perror("otvoriť");
Návrat -1;
Na čítanie klastrov súborov organizujeme slučku:
Pre (i = 0; i< num; i++) {
Načítame obsah klastra do vyrovnávacej pamäte tmp_buff a uložíme ho do samostatného súboru:
< 0) return -1;
< 0) {
Perror("zapis");
Close(n);
Návrat -1;
Z FAT16 čítame číslo nasledujúceho klastra obsadeného týmto súborom. Ak je toto posledný klaster, prerušíme cyklus a vrátime sa k hlavnej funkcii:
#ifdef DEBUG
Printf("OK. Prečítané ");
Printf("ďalší klaster súboru - 0x%X .. ", ďalší_klaster);
#koniec Ak
If(next_cluster == EOF_FAT16) (
#ifdef DEBUG
Printf("posledný klaster.");
#koniec Ak
Free(tmp_buff);
Close(n);
Návrat ++i;
#ifdef DEBUG
Printf("prestať čítať");
#koniec Ak
Návrat i;
Čítanie zavádzacieho sektora FAT16 vykonáva funkcia read_fbs(). Výsledok je umiestnený v globálnej štruktúre fbs:
int read_fbs()
If(read(hard,(__u8 *)&fbs, sizeof(fbs))< 0) return -1;
Návrat 0;
Čítanie alokačnej tabuľky súborov systému súborov FAT16 sa vykonáva funkciou read_fat16():
int read_fat16()
U64 hľadať = (__u64)(fbs.rezervované) * 512; // posun na FAT16 od začiatku oddielu
Fat16 = (void *)malloc(fat16_size);
If(pread64(hard, (__u8 *)fat16, fat16_veľkosť, hľadať)< 0) return -1;
Návrat 0;
Funkcia read_root_dentry() číta koreňový adresár:
int read_root_dentry()
U64 seek = (__u64)fbs.rezervované * 512 + fat16_size * fbs.fats; // posun do koreňového adresára od začiatku oddielu
Root_size = 32 * dir_entries; // výpočet veľkosti koreňového adresára
Dir_entry = (__u8 *)malloc (veľkosť_korena);
If(!dir_entry) return -1;
Memset(položka_adresára, 0, veľkosť_korena);
If(pread64(hard, dir_entry, root_size, seek)< 0) return -1;
Návrat 0;
Čítanie klastra patriacemu súboru sa vykonáva funkciou read_cluster(). Vstupnými parametrami funkcie sú číslo klastra cluster_num a ukazovateľ na vyrovnávaciu pamäť __u8 *tmp_buff, kde by sa mal umiestniť výsledok čítania. Odsadenie klastra na oddiele sa vypočíta pomocou vzorca (pozri):
SEEK = DATA_START + (CLUSTER_NUM - 2) * BYTE_PER_CLUSTER,
- HĽADAŤ– offset ku klastru na oddiele
- DATA_START– začiatok dátovej oblasti
- CLUSTER_NUM– sériové číslo klastra
- BYTE_PER_CLUSTER– veľkosť klastra v bajtoch
int read_cluster(__u16 cluster_num, __u8 *tmp_buff)
U64 seek = (__u64)(byte_per_cluster) * (cluster_num - 2) + data_start; // výpočet posunu klastra
< 0) return -1;
Návrat 0;
Funkcia read_directory načíta položky z adresára (nie z koreňového adresára) a umiestni výsledok do pamäťového miesta, na ktoré je nastavený ukazovateľ dir_entry:
int read_directory(__u16 start_cluster)
Int i = 1;
U16 ďalší_klaster;
Pre (; ;i++) (
Alokujeme pamäť na uloženie obsahu adresára, prečítame obsah štartovacieho klastra a získame hodnotu nasledujúceho klastra z tabuľky FAT16:
If(!dir_entry) return -1;
< 0) return -1;
Ďalší_klaster = tuk16;
Uložme obsah adresára do samostatného súboru (pre kontrolu):
#ifdef DEBUG
Printf("Ďalší klaster - 0x%X", ďalší_klaster);
Tuk = open("dir16", O_CREAT|O_WRONLY, 0600);
Write(fat, dir_entry, root_size);
Close(tuk);
#koniec Ak
Ak sa dosiahne posledný klaster, opustíme cyklus, v opačnom prípade pokračujeme v čítaní adresára a zväčšujeme veľkosť vyrovnávacej pamäte dir_entry o ďalší klaster:
If(next_cluster & EOF_FAT16) break;
Start_cluster = ďalší_klaster;
Návrat 0;
Funkcia get_dentry() hľadá v obsahu adresára prvok zodpovedajúci hľadanému súboru. Vstupnými parametrami tejto funkcie sú ukazovateľ na štruktúru struct split_name *sn obsahujúcu prvky krátkeho názvu súboru:
Int i = 0;
Globálna vyrovnávacia pamäť dir_entry obsahuje pole položiek adresára, v ktorom budeme hľadať položku súboru (alebo adresára). Na vyhľadávanie organizujeme cyklus. V tele cyklu skopírujeme prvky adresára do globálnej dentry štruktúry a porovnávame hodnoty polí name a ext tejto štruktúry so zodpovedajúcimi poľami štruktúry split_name *sn. Zhoda týchto polí znamená, že sme našli záznam pre súbor, ktorý hľadáme v poli prvkov adresára:
pre (; ; i++) (
If(!(memcmp(dentry.name, sn->meno, sn->meno_len)) &&
!(memcmp(dentry.ext, sn->ext, sn->ext_len)))
Prestávka;
If(!dentry.name) return -1;
#ifdef DEBUG
Printf("meno - %s ", dentry.meno);
Printf("start cluster - 0x%X ", dentry.start);
Printf("veľkosť súboru - %u ", dentry.size);
Printf("attrib súboru - 0x%X ", dentry.attr);
#koniec Ak
Návrat 0;
Všetok vyššie uvedený kód sa nachádza v adresári FAT16, súbor fat16.c. Ak chcete získať spustiteľný modul, vytvorte súbor Makefile s nasledujúcim obsahom:
INCDIR = /usr/src/linux/include
FÓNIA = čistý
Tuk16: tuk16.o rozdelený.o
Gcc -I$(INCDIR) $^ -g -o $@
%.o: %.c
Gcc -I$(INCDIR) -DDEBUG -c $^
Vyčistiť:
Rm -f *.o
Rm -f ./tuk16
Softvérová implementácia algoritmu na čítanie súboru z logického oddielu so súborovým systémom FAT12
Vo všeobecnosti je algoritmus na čítanie súboru z oblasti FAT12 identický s algoritmom na čítanie súboru z oblasti FAT16. Rozdiel spočíva v postupe čítania prvkov z tabuľky FAT12. Tabuľku FAT16 sme považovali za jednoduché pole 16-bitových prvkov. Na čítanie prvkov tabuľky FAT12 sa navrhuje nasledujúci algoritmus:
- vynásobte číslo prvku číslom 1,5;
- extrahovať 16-bitové slovo z FAT použitím výsledku predchádzajúcej operácie ako ofsetu;
- ak je číslo prvku párne, vykonajte operáciu AND na prečítanom slove a maske 0x0FFF. Ak je číslo nepárne, posuňte prečítané slovo z tabuľky o 4 bity smerom k nižším číslicam.
Na základe tohto algoritmu implementujeme funkciu čítania prvkov z tabuľky FAT12:
int get_cluster(__u16 cluster_num)
U16 hľadať;
skupina U16;
Vypočítame offset v tabuľke FAT12 a prečítame 16-bitové slovo z tabuľky:
Hľadať = (cluster_num * 3) / 2;
Memcpy((__u8 *)&clust, (__u8 *)(tuk12 + hľadať), 2);
Ak je začiatočné číslo klastra párne číslo, posunieme hodnotu načítanú z tabuľky o 4 bity smerom k bitom nižšieho rádu, ak je nepárne, spočítame to 0x0FFF:
If(cluster_num % 2) cluster >>= 4;
Else zhluk &= 0x0FFF;
Tento fragment je možné implementovať aj v assembleri:
" xorw %%ax, %%ax "
"btw $0, %%cx"
"jnc 1f"
"shrw $4, %%dx"
"jmp 2f"
"1: andw $0x0FFF, %%dx"
"2: movw %%dx, %%ax"
:"=a" (ďalší)
:"d" (cluster), "c" (cluster_num));
Vrátime výsledok:
Returnclust;
Pozrime sa bližšie na samotný algoritmus. Predpokladajme, že súbor bol vytvorený na oddiele FAT12, ktorý zaberá 9. a 10. klaster. Každý prvok FAT12 zaberá 12 bitov. Pretože z tabuľky načítame 16-bitové prvky, potom sa posun k 9. prvku bude rovnať 13 bajtom (9 * 1,5 = 13, zvyšok sa zahodí), pričom spodné 4 bity budú patriť 8. prvku FAT. Treba ich zahodiť a na to stačí posunúť čítací prvok o 4 bity smerom k nižším číslicam, čo zabezpečuje algoritmus. Posun k 10. prvku bude 15 bajtov a najvýznamnejšie 4 bity budú patriť 11. prvku FAT. Na ich vyradenie je potrebné vykonať operáciu AND na 10. prvku a maske 0x0FFF, čo tiež zodpovedá vyššie uvedenému algoritmu.
Zdrojové texty modulu na čítanie súboru z FAT12 partície sa nachádzajú v adresári FAT12, súbor fat12.c.
Softvérová implementácia algoritmu na čítanie súboru z logického oddielu so systémom súborov FAT32
Algoritmus na čítanie súboru z oddielu so systémom súborov FAT32 sa prakticky nelíši od algoritmu pre FAT16, okrem toho, že v systéme FAT32 môže byť koreňový adresár umiestnený kdekoľvek na oddiele a môže mať ľubovoľnú veľkosť. Preto, aby to bolo zaujímavejšie, skomplikujme si úlohu - predpokladajme, že poznáme iba číslo oblasti so súborovým systémom FAT32. Ak chcete prečítať informácie z tohto oddielu, musíte najskôr určiť jeho súradnice - posun k oddielu od začiatku disku. A na to musíte mať predstavu o logickej štruktúre pevného disku.
Logická štruktúra pevného disku
Uvažujme o logickej štruktúre pevného disku, ktorý je v súlade so štandardom spoločnosti Microsoft – „hlavný oddiel – rozšírený oddiel – oddiely mimo DOS“.
Priestor na pevnom disku môže byť usporiadaný do jedného alebo viacerých oddielov a oddiely môžu obsahovať jednu alebo viacero logických jednotiek.
Master Boot Record (MBR) sa nachádza na pevnom disku na fyzickej adrese 0-0-1. Štruktúra MBR obsahuje nasledujúce prvky:
- nesystémový bootstrap (NSB);
- tabuľka popisujúca diskové oblasti (partition table, PT). Nachádza sa v MBR s posunom 0x1BE a zaberá 64 bajtov;
- Podpis MBR. Posledné dva bajty MBR musia obsahovať číslo 0xAA55.
Tabuľka oblastí popisuje umiestnenie a charakteristiky oblastí dostupných na pevnom disku. Diskové oddiely môžu byť dvoch typov - primárne (primárne, hlavné) a rozšírené (rozšírené). Maximálny počet primárnych oddielov je štyri. Prítomnosť aspoň jedného primárneho oddielu na disku je povinná. Rozšírený oddiel môže byť rozdelený na veľké množstvo pododdielov - logických jednotiek. Zjednodušená štruktúra MBR je uvedená v tabuľke 7. Tabuľka oblastí sa nachádza na konci MBR, na popis oblasti v tabuľke je alokovaných 16 bajtov.
Tabuľka 7. Štruktúra MBR
Zaujatosť Veľkosť, bajty 0 446 0x1BE 16 0x1CE 16 0x1DE 16 0x1EE 16 0x1FE 2
Štruktúra záznamu tabuľky oddielov je uvedená v tabuľke 8.
Tabuľka 8. Štruktúra záznamu tabuľky oddielov
Zaujatosť | Veľkosť, bajty | Obsah |
0x00 | 1 | Znak aktivity (0 - oblasť nie je aktívna, 0x80 - oblasť je aktívna) |
0x01 | 1 | Číslo hlavy disku, od ktorej začína partícia |
0x02 | 2 | Číslo valca a číslo sektora, od ktorého začína sekcia |
0x04 | 1 | Kód typu oddielu ID systému |
0x05 | 1 | Číslo hlavy disku, kde končí partícia |
0x06 | 2 | Číslo valca a číslo sektora, ktorým sa sekcia končí |
0x08 | 4 | Absolútne (logické) číslo počiatočného sektora oddielu |
0x0C | 4 | Veľkosť oddielu (počet sektorov) |
Prvý bajt v prvku sekcie je príznak aktivity sekcie (0 – neaktívny, 0x80 – aktívny). Používa sa na určenie, či je oblasť zavádzaná zo systému a či je z nej potrebné načítať operačný systém pri štarte počítača. Aktívna môže byť iba jedna sekcia. Za príznakom aktivity oddielu nasledujú súradnice začiatku oddielu - tri bajty označujúce číslo hlavy, číslo sektora a číslo cylindra. Čísla cylindra a sektorov sú uvedené vo formáte prerušenia Int 0x13, t.j. bity 0-5 obsahujú číslo sektora, bity 6-7 – dva najvýznamnejšie bity 10-bitového čísla cylindra, bity 8-15 – najmenej významných osem bitov čísla cylindra. Potom nasleduje kód System ID, ktorý označuje, že táto sekcia patrí konkrétnemu operačnému systému. Identifikátor zaberá jeden bajt. Za systémovým identifikátorom sú súradnice konca sekcie - tri bajty obsahujúce čísla hlavy, sektora a valca, resp. Ďalšie štyri bajty predstavujú počet sektorov pred oddielom a posledné štyri bajty predstavujú veľkosť oddielu v sektoroch.
Prvok tabuľky oddielov teda možno opísať pomocou nasledujúcej štruktúry:
struct pt_struct (
bootovateľný U8; // príznak aktivity sekcie
U8 štart_part; // súradnice začiatku úseku
U8 typ_diel; // systémový identifikátor
U8 koncová_časť; // súradnice konca úseku
U32 sekta_pred; // počet sektorov pred oddielom
U32 sekta_celkom; // veľkosť oddielu v sektoroch (počet sektorov v oddiele)
Prvok primárneho oddielu ukazuje priamo na zavádzací sektor logického disku (v primárnom oddiele je vždy len jeden logický disk) a prvok rozšíreného oddielu ukazuje priamo na zoznam logických diskov tvorený štruktúrami nazývanými sekundárny MBR (sekundárny). MBR, SMBR).
Každý disk rozšíreného oddielu má svoj vlastný blok SMBR. SMBR má štruktúru podobnú MBR, ale nemá zavádzací záznam (vyplnený nulami) a používajú sa iba dve zo štyroch polí deskriptora oddielu. Prvý prvok sekcie ukazuje na logický disk, druhý prvok ukazuje na ďalšiu štruktúru SMBR v zozname. Posledný SMBR zoznamu obsahuje vo svojom druhom prvku kód oddielu nula.
Vráťme sa k modulu na čítanie súboru z oblasti FAT32.
Hlavičkové súbory:
#include
#include
#include
#include
#include
Podpis MBR:
#define PODPIS 0xAA55
Súbor zariadenia, z ktorého sa budú čítať informácie o oddiele:
#define DEVICE "/dev/hda"
Veľkosť prvku tabuľky oddielov (16 bajtov):
#define PT_SIZE 0x10
Nasledujúce pole štruktúr mapuje kód typu sekcie na jej symbolickú reprezentáciu:
struct systypes (
U8 časť_typ;
U8 *názov_časti;
struct systypes i386_sys_types = (
(0x00, "Prázdne"),
(0x01, "FAT12"),
(0x04, "FAT16<32M"},
(0x05, "Rozšírené"),
(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 rozšírený"),
(0x07, "HPFS/NTFS")
Poďme určiť počet prvkov v poli i386_sys_types pomocou makra PART_NUM:
#define PART_NUM (sizeof(i386_sys_types) / sizeof(i386_sys_types))
Stanovme limit na počet logických jednotiek:
#define MAX_PART 20
Nasledujúce štruktúrne pole bude obsahovať informácie o logických jednotkách na zariadení (pevnom disku):
struct pt_struct (
bootovateľný U8;
U8 štart_part;
U8 typ_diel;
U8 koncová_časť;
U32 sekta_pred;
U32 sekta_celkom;
) pt_t;
int ťažké; // deskriptor súboru zariadenia
U8 mbr; // tu spočítajte MBR
Číslo oblasti, na ktorej bol vytvorený súborový systém FAT32:
#define FAT32_PART_NUM 5
Štruktúry zavádzacieho sektora, sektora FSInfo a položky adresára (definované v súbore
struct fat_boot_sector fbs;
struct fat_boot_fsinfo fsinfo;
struct msdos_dir_entry dentry;
U32 *tuk32 = NULL; // tu skopírujte tabuľku FAT32
U16 sektor_veľkosť; // veľkosť sektora (z FAT32)
U16 dir_entries; // 0 pre FAT32
sektory U16; // počet sektorov na oddiele
U32 fat32_size; // Veľkosť FAT32
U32 data_start; // začiatok dátovej oblasti
U16 byte_per_cluster; // koľko bajtov je v klastri (veľkosť klastra v bajtoch)
U32 ďalší_klaster; // ďalší klaster v reťazci
U32 root_cluster; // ROOT klaster - počiatočný klaster koreňového adresára
U8 *dir_entry = NULL; // ukazovateľ na položky adresára
U64 start_seek = 0; // počiatočný posun k oddielu (v bajtoch)
Hlavná funkcia:
int main()
Int num = 0;
Int cluster_num = 5; // koľko klastrov sa má prečítať zo súboru
U8 *plná_cesta = "/Priečinok1/Priečinok2/readme"; // súbor na čítanie
Otvoríme zariadenie, získame informácie o tabuľke oddielov na zariadení a zobrazíme informácie o oddieloch:
Hard = open(DEV_NAME, O_RDONLY);
Ak (tvrdé< 0) {
Chyba(DEV_NAME);
Exit(-1);
If(get_pt_info(tvrdé)< 0) {
Perror("get_pt_info");
Exit(-1);
Show_pt_info();
Vypočítame počiatočný posun k oddielu:
Start_seek = (__u64)(pt_t.sect_before) * 512;
Prečítajte si klastre patriace k súboru:
Num = fat32_read_file(úplná_cesta, číslo_klastra);
Ak(č< 0) perror("fat32_read_file");
Else printf("Prečítať %d klastre\n", num);
Zavrieť (tvrdo);
Návrat 0;
Informácie o tabuľke oddielov číta funkcia get_pt_info():
int get_pt_info (int hard)
Int i = 0;
U64 hľadať;
Čítame tabuľku oddielov z MBR a skontrolujeme podpis:
Read_main_ptable(hard);
If(check_sign()< 0) {
Printf("Neplatný podpis!\n");
Návrat -1;
Hľadáme identifikátor rozšírenej sekcie. Ak existuje, vypočítame posun k rozšírenému oddielu a prečítame informácie o logických jednotkách:
pre (; i< 4; i++) {
If((pt_t[i].type_part == 0xF) || \
(pt_t[i].type_part == 0x5) || \
(pt_t[i].type_part == 0x0C)) (
Hľadať = (__u64)pt_t[i].sect_before * 512;
Read_ext_ptable(tvrdé, hľadať);
Prestávka;
Návrat 0;
Funkcia čítania tabuľky oddielov read_main_ptable():
void read_main_ptable (int hard)
If(read(hard, mbr, 512)< 0) {
Perror("čítať");
Zavrieť (tvrdo);
Exit(-1);
Memset((void *)pt_t, 0, (PT_SIZE * 4));
Memcpy((void *)pt_t, mbr + 0x1BE, (PT_SIZE * 4));
Návrat;
Funkcia kontroly podpisu check_sign():
int check_sign()
znak U16 = 0;
Memcpy((void *)&sign, (void *)(mbr + 0x1FE), 2);
#ifdef DEBUG
Printf("Podpis - 0x%X\n", znamienko);
#koniec Ak
If(znamienko != PODPIS) return -1;
Návrat 0;
Funkcia čítania rozšírenej tabuľky oddielov:
void read_ext_ptable (int ťažké, __u64 hľadať)
Int num = 4; // od tejto pozície sa pole štruktúr pt_t zaplní informáciami o logických jednotkách
U8 smbr;
Vstupné Data:
- ťažké– deskriptor súboru zariadenia;
- hľadať– posun k rozšírenému oddielu od začiatku disku (v bajtoch).
Na získanie informácií o logických jednotkách organizujeme slučku:
Pre(;;num++) (
Čítame SMBR, ktorý sa nachádza pri posune hľadania od začiatku disku:
Memset((void *)smbr, 0, 512);
Pread64(tvrde, smbr, 512, hladat);
Vyplníme dva prvky tabuľky pt_t, počnúc od pozície č. Prvý prvok bude ukazovať na logickú jednotku a druhý bude ukazovať na nasledujúcu štruktúru SMBR:
Memset((void *)&pt_t, 0, PT_SIZE * 2);
Memcpy((void *)&pt_t, smbr + 0x1BE, PT_SIZE * 2);
Upravili sme pole „Číslo počiatočného sektora“ - počíta sa od začiatku disku:
Pt_t.sect_before += (hľadať / 512);
Ak je kód typu oddielu nula, potom už neexistujú žiadne logické jednotky:
If(!(pt_t.type_part)) break;
Vypočítame offset k nasledujúcemu SMBR:
Hľadať = ((__u64)(pt_t.sect_before + pt_t.sect_total)) * 512;
Návrat;
Funkcia show_pt_info() zobrazuje informácie o nájdených logických jednotkách na zariadení:
void show_pt_info()
Int i = 0, n;
#ifdef DEBUG
Printf("Počet oblastí na disku je %d\n", PART_NUM);
#koniec Ak
Pre (; i< MAX_PART; i++) {
If(!pt_t[i].type_part) break;
Printf("\nTyp oblasti %d - ", i);
For(n = 0; n< PART_NUM; n++) {
If(pt_t[i].type_part == i386_sys_types[n].part_type) (
Printf("%s\n", i386_sys_types[n].názov_časti);
Prestávka;
If(n == ČASŤ_NUM) printf("neznámy typ\n");
Printf("Zavádzací znak - 0x%X\n", pt_t[i].bootable);
Printf("Sektory v oddiele %d - %d\n", i, pt_t[i].sect_total);
Printf("Sektory pred oddielom %d - %d\n\n", i, pt_t[i].sect_before);
Návrat;
Čítanie klastrov súborov z oblasti FAT32 sa vykonáva pomocou funkcie fat32_read_file(). Táto funkcia má veľa spoločného s funkciou fat16_read_file(), takže podrobné komentáre nájdete v bode 6:
int fat32_read_file(__u8 *úplná_cesta, int num)
Struct split_name sn;
U8 tmp_name_buff;
Int i = 1, n;
U32 start_cluster, next_cluster;
U8 *tmp_buff;
Prípravné operácie - vyčistíme vyrovnávaciu pamäť, štruktúru a skontrolujeme prvú lomku:
Memset(tmp_name_buff, 0, SHORT_NAME);
Memset((void *)&sn, 0, sizeof(struct split_name));
If(full_path != "/") return -1;
Čítanie zavádzacieho sektora:
If(read_fbs()< 0) return -1;
Memcpy((void *)&veľkosť_sektora, (void *)fbs.veľkosť_sektora, 2);
Memcpy((void *)&dir_entries, (void *)fbs.dir_entries, 2);
Memcpy((void *)§ors, (void *)fbs.sectors, 2);
Čítame štruktúru FSInfo a zobrazujeme podpis, ktorý sa v nej nachádza:
If(read_fs_info()< 0) return -1;
Printf("Podpis1 - 0x%X\n", fsinfo.podpis1);
Printf("Podpis2 - 0x%X\n", fsinfo.podpis2);
Fat32_size = fbs.fat32_length * 512; // Veľkosť FAT32 v bajtoch
Data_start = 512 * fbs.reserved + fat32_size * 2; // začiatok dátového poľa
Byte_per_cluster = fbs.cluster_size * 512; // veľkosť klastra v bajtoch
Root_cluster = fbs.root_cluster; // číslo klastra koreňového adresára
Čítanie FAT32:
If(read_fat32()< 0) return -1;
Pridelenie pamäte pre záznamy v adresári:
Dir_entry = (__u8 *)malloc(byte_per_cluster);
If(!dir_entry) return -1;
Čítanie koreňového adresára:
If(read_directory(root_cluster)< 0) return -1;
Analyzujeme celú cestu k súboru a rozdelíme každý prvok na jeho komponenty:
Kým (1) (
Memset(tmp_name_buff, 0, SHORT_NAME);
Memset((void *)&sn, 0, sizeof(struct split_name));
For(n = 0; n< SHORT_NAME; n++, i++) {
Tmp_name_buff[n] = úplná_cesta[i];
If((tmp_name_buff[n] == "/") || (tmp_name_buff[n] == "\0")) (
I++;
Prestávka;
Tmp_name_buff[n] = "\0";
If(split_name(tmp_name_buff, &sn)< 0) {
Printf("neplatné meno\n");
Návrat -1;
If(get_dentry(&sn)< 0) {
Printf("Žiadny takýto súbor!\n");
Návrat -1;
Ak chcete získať počiatočné číslo klastra v systéme súborov FAT32, musíte použiť najvyššie slovo z čísla prvého klastra súboru - pole starthi štruktúry dentry:
Start_cluster = (((__u32)dentry.starthi<< 16) | dentry.start);
Kontrola bajtu atribútu:
If(dentry.attr & 0x10) ( // toto je adresár
If(read_directory(start_cluster)< 0) return -1;
Ďalej;
If(dentry.attr & 0x20) ( // a toto je súbor
Tmp_buff = (__u8 *)malloc (byte_per_cluster);
N = open("clust", O_CREAT|O_RDWR, 0600);
Ak(n< 0) {
Perror("otvoriť");
Návrat -1;
Printf("prvý klaster súboru - 0x%X .. ", start_cluster);
Pre (i = 0; i< num; i++) {
Memset(tmp_buff, 0, byte_per_cluster);
If(read_cluster(start_cluster, tmp_buff)< 0) return -1;
If(write(n, tmp_buff, byte_per_cluster)< 0) {
Perror("zapis");
Návrat -1;
If(next_cluster == EOF_FAT32) (
Free(tmp_buff);
Close(n);
Návrat ++i;
Start_cluster = ďalší_klaster;
Návrat i;
Účelom ďalších troch funkcií je získanie obsahu systémovej oblasti, t.j. boot sektor, štruktúra FSInfo a tabuľka FAT32:
1) funkcia read_fbs() číta boot sektor:
int read_fbs()
If(pread64(hard, (__u8 *)&fbs, sizeof(fbs), start_seek)< 0) return -1;
Návrat 0;
2) funkcia read_fs_info() číta štruktúru FSInfo:
int read_fs_info()
U64 seek = (__u64)fbs.info_sector * 512 + start_seek;
If(pread64(tvrdé, (__u8 *)&fsinfo, sizeof(fsinfo), hľadať)< 0) return -1;
Návrat 0;
3) funkcia read_fat32() číta tabuľku FAT32:
int read_fat32()
U64 seek = (__u64)fbs.rezervované * 512 + start_seek;
Fat32 = (void *)malloc(veľkosť_tuku32);
If(!fat32) vráti -1;
If(pread64(hard, (__u8 *)fat32, fat32_size, seek)< 0) return -1;
Návrat 0;
Funkcia read_cluster() načíta klaster so zadaným číslom:
int read_cluster(__u32 cluster_num, __u8 *tmp_buff)
U64 seek = (__u64)(byte_per_cluster) * (cluster_num - 2) + data_start + start_seek;
If(pread64(hard, tmp_buff, byte_per_cluster, seek)< 0) return -1;
Návrat 0;
Funkcia read_directory() sa používa na čítanie adresárov (vrátane koreňového adresára):
int read_directory(__u32 start_cluster)
Int i = 2;
U32 ďalší_klaster;
Parametre funkcie sú počiatočným klastrom adresára. Načítame obsah adresára do globálnej vyrovnávacej pamäte dir_entry:
If(read_cluster(start_cluster, dir_entry)< 0) return -1;
Ďalší_klaster = tuk32;
Ak adresár zaberá jeden klaster, ukončite ho; ak nie, zväčšite veľkosť pamäte a pokračujte v čítaní:
Pre (; ;i++) (
Start_cluster = ďalší_klaster;
Dir_entry = (__u8 *)realloc(dir_entry, i * byte_per_cluster);
If(!dir_entry) return -1;
If(read_cluster(start_cluster, (dir_entry + (i - 1) * byte_per_cluster))< 0) return -1;
Ďalší_klaster = tuk32;
If((ďalší_klaster == EOF_FAT32) || (ďalší_klaster == 0xFFFFFF8)) return 0;
Návrat 0;
Posledná funkcia, na ktorú sa pozrieme, hľadá v obsahu adresára prvok, ktorý sa zhoduje s hľadaným súborom:
int get_dentry(struct split_name *sn)
Int i = 0;
Ukazovateľ dir_entry je nastavený na oblasť pamäte obsahujúcu pole položiek adresára, v ktorom budeme hľadať súbor (alebo adresár). Na vyhľadávanie zorganizujeme cyklus a nájdený záznam umiestnime do globálnej zubnej štruktúry:
Pre(;;i++) (
Memcpy((void *)&dentry, dir_entry + i * sizeof(dentry), sizeof(dentry));
If(!(memcmp(dentry.name, sn->meno, sn->meno_len)) &&
!(memcmp(dentry.ext, sn->ext, sn->ext_len)))
Prestávka;
If(!dentry.name) return -1;
Návrat 0;
Týmto končíme našu recenziu modulu na čítanie súboru z oblasti FAT32.
Zdrojový kód modulu sa nachádza v adresári FAT32, súbor fat32.c.
Rozdiely v organizácii ukladania záznamov súborov do adresárov pre súborové systémy FAT a EXT2
Niekoľko slov o rozdieloch v organizácii ukladania záznamov súborov do adresárov pre súborové systémy FAT a EXT2. Štruktúra súborového systému EXT2 bola diskutovaná v .
Práve sme sa zoznámili s FAT - v ňom majú všetky adresárové prvky pevnú hodnotu. Po vytvorení súboru ovládač súborového systému vyhľadá prvú neobsadenú pozíciu a vyplní ju informáciami o súbore. Ak sa dĺžka adresára nezmestí do jedného klastra, pridelí sa mu iný klaster atď.
Pozrime sa, ako sa veci majú v EXT2.
Povedzme, že máme oddiel so súborovým systémom EXT2, veľkosť bloku je 4096 bajtov. V tejto časti vytvoríme adresár. Veľkosť adresára sa bude rovnať veľkosti bloku - 4096 bajtov. V adresári operačný systém okamžite vytvorí dva záznamy – záznam pre aktuálny adresár a záznam pre nadradený adresár. Aktuálny záznam v adresári bude mať 12 bajtov, zatiaľ čo záznam rodiča bude mať dĺžku 4084 bajtov. V tomto adresári vytvoríme súbor. Potom budú v adresári tri záznamy - záznam aktuálneho adresára s dĺžkou 12 bajtov, záznam nadradeného adresára s dĺžkou 12 bajtov a záznam vytvoreného súboru s dĺžkou ako ste pravdepodobne uhádli, 4072 bajtov. Ak vytvorený súbor vymažeme, dĺžka položky nadradeného adresára sa opäť zvýši na 4084 bajtov.
Pri vytváraní súboru teda ovládač súborového systému EXT2 hľadá záznam maximálnej dĺžky v adresári a rozdeľuje ho, čím vytvára priestor pre nový záznam. Ak stále nie je dostatok miesta, pre adresár sa pridelí ďalší blok a dĺžka adresára bude 8192 bajtov.
A na záver malá úprava článku „Architektúra súborového systému EXT2“.
Táto zmena sa týka funkcie get_i_num() na určenie čísla inódu podľa názvu súboru. Stará verzia tejto funkcie vyzerala takto:
int get_i_num(char *meno)
Int i = 0, rec_len = 0;
Struct ext2_dir_entry_2 dent;
Pre (; i< 700; i++) {
If(!memcmp(dent.name, name, dent.name_len)) break;
Rec_len += dent.rec_len;
Return dent.inode;
Opravená verzia:
int get_i_num(char *meno)
* Parametrom funkcie je názov súboru. Návratová hodnota je číslo inódu súboru.
Int rec_len = 0;
Struct ext2_dir_entry_2 dent; // táto štruktúra popisuje formát položky koreňového adresára:
* Globálna vyrovnávacia pamäť obsahuje pole položiek adresára. Ak chcete určiť sériové číslo súboru inode, musíte nájsť
* v tomto poli je položka s názvom tohto súboru. Aby sme to dosiahli, organizujeme slučku:
Pre(;;) (
/* Skopírujte položky adresára do štruktúry dent: */
Memcpy((void *)&dent, (buff + rec_len), sizeof(dent));
* Dĺžka súboru nula znamená, že sme prešli všetky položky adresára
* a nenašli sa žiadne záznamy s názvom nášho súboru. Takže je čas vrátiť sa:
If(!dent.name_len) return -1;
/* Vyhľadávanie sa vykonáva porovnaním názvov súborov. Ak sa mená zhodujú, opustíme cyklus: */
If(!memcmp(dent.name, name, strlen(name))) break;
/* Ak sa mená nezhodujú, prejdite na ďalšiu položku: */
Rec_len += dent.rec_len;
/* Ak je to úspešné, vráťte číslo inodu súboru: */
Return dent.inode;
Literatúra:
- V. Kulakov. Programovanie na úrovni hardvéru: špeciálna príručka. 2. vyd. / – Petrohrad: Peter, 2003 – 848 s.
- A.V.Gordeev, A.Yu.Molchanov. Systémový softvér / – Petrohrad: Peter – 2002
- Meshkov V. Architektúra súborového systému ext2. – Časopis „Správca systému“, číslo 11(12), november 2003 – 26-32 s.
V kontakte s
TUK(Angličtina) Súbor Pridelenie Tabuľka- „tabuľka prideľovania súborov“) je klasická architektúra súborového systému, ktorá je vďaka svojej jednoduchosti stále široko používaná pre flash disky. Používa sa v disketách a niektorých iných pamäťových médiách. Predtým používané na pevných diskoch.
Súborový systém vyvinuli Bill Gates a Mark MacDonald v roku 1977 a pôvodne sa používal v operačnom systéme 86-DOS. 86-DOS následne získal Microsoft a stal sa základom pre MS-DOS 1.0, vydaný v auguste 1981. FAT bol navrhnutý na prácu s disketami menšími ako 1 MB a pôvodne neposkytoval podporu pre pevné disky.
V súčasnosti existujú štyri verzie FAT - FAT8, FAT12, FAT16 A FAT32. Líšia sa bitovou hĺbkou záznamov v štruktúre disku, tzn počet bitov pridelených na uloženie čísla klastra. FAT12 sa používa hlavne pre diskety, FAT16 pre malé disky, FAT32 pre pevné disky. Bol vyvinutý nový súborový systém založený na FAT exFAT(extended FAT), používa sa predovšetkým pre flash disky.
Súborový systém FAT zapĺňa voľné miesto na disku postupne od začiatku do konca. Pri vytváraní nového súboru alebo zvyšovaní existujúceho súboru hľadá prvý voľný klaster v tabuľke prideľovania súborov. Ak boli niektoré súbory odstránené a iné zmenili veľkosť, výsledné prázdne zhluky budú rozptýlené po disku. Ak klastre obsahujúce údaje súboru nie sú umiestnené v rade, potom je súbor umiestnený roztrieštené. Silne fragmentované súbory výrazne znižujú efektivitu, pretože hlavy na čítanie a zápis sa budú musieť pri hľadaní ďalšieho záznamu súboru presúvať z jednej oblasti disku na druhú. Odporúča sa, aby klastre vyhradené na uloženie súboru boli umiestnené vedľa seba, pretože to skracuje čas potrebný na jeho hľadanie. Dá sa to však urobiť len pomocou špeciálneho programu, tento postup sa nazýva defragmentácia súbor.
Ďalšou nevýhodou FAT je, že jeho výkon závisí od počtu súborov v jednom adresári. Ak existuje veľký počet súborov (približne tisíc), operácia čítania zoznamu súborov v adresári môže trvať niekoľko minút. FAT neuchováva informácie, ako je vlastníctvo súboru alebo povolenia súborov.
FAT je jednoduchý súborový systém, ktorý nezabraňuje poškodeniu súborov v dôsledku abnormálneho vypnutia počítača, je to jeden z najbežnejších súborových systémov a je podporovaný väčšinou operačných systémov.
Organizácia systému súborov tuku
Všetky moderné diskové operačné systémy poskytujú vytvorenie súborového systému určeného na ukladanie dát na disky a poskytovanie prístupu k nim.Aby sa dáta mohli zapisovať na disk, musí byť jeho povrch štruktúrovaný – t.j. rozdeliť do sektorov A stopy.
A-track
C-klaster
Obrázok 1 - Štruktúra disku
Cesty- sú to sústredné kruhy pokrývajúce povrch disku. Skladbe najbližšie k okraju disku je priradené číslo 0, nasledujúcej - 1 atď. Ak je disketa obojstranná, potom sú obe strany očíslované. Číslo prvej strany je 0, číslo druhej je 1.
Každá trať je rozdelená na úseky tzv sektorov. Sektorom sú tiež priradené čísla. Prvý sektor na trati má pridelené číslo 1, druhý - 2 atď.
Pevný disk pozostáva z jednej alebo viacerých okrúhlych platní. Oba povrchy platne slúžia na ukladanie informácií. Každý povrch je rozdelený na dráhy, dráhy zasa na sektory. Cesty s rovnakým polomerom sú valec. Všetky nulové stopy teda tvoria valec číslo nula, stopy číslo 1 tvoria valec číslo 1 atď.
Preto povrch pevného disku možno považovať za trojrozmernú maticu, ktorej rozmery sú čísla povrch, valec A sektorov. Valec sa chápe ako súbor všetkých dráh patriacich rôznym povrchom a umiestnených v rovnakej vzdialenosti od osi otáčania.
Zakaždým, keď používam FatF, myslím, že by bolo pekné pochopiť, ako všetko vo vnútri funguje. Túto otázku som dlho odkladal a konečne sa ľady prelomili. Globálnym cieľom je teda fajčiť pamäťové karty, ak to vyjde do detailov, aktuálnym cieľom je vysporiadať sa so súborovým systémom.
Okamžite poviem, že som nemal za cieľ napísať vlastný ovládač alebo podrobne porozumieť zložitosti, len ma to zaujímalo. Úloha je celkom jednoduchá na pochopenie, takže tu nebudú žiadne „kódy“.
Prvá vec, ktorú musíme pochopiť, je, že pri priamej komunikácii s pamäťovou kartou môžeme buď čítať alebo zapisovať 512 bajtov, nie sú dané žiadne ďalšie akcie. Keďže súbory neustále kopírujeme a vymazávame a veľkosti súborov sú vždy iné, na karte sa objavia prázdne oblasti zmiešané so zaznamenanými. Aby sa používateľ nemusel starať o umiestňovanie údajov, existuje vrstva, ktorá sa o tieto starosti stará, a to je súborový systém.
Ako už bolo spomenuté vyššie, zapisovať a čítať môžete len v násobkoch 512 bajtov, t.j. 1 sektor. Existuje aj koncept - klaster je jednoducho niekoľko sektorov, napríklad ak je veľkosť klastra 16 kB, znamená to, že má 16 000/512 = 31,25, alebo skôr 32 sektorov, a skutočná veľkosť klastra je 16 384 bajtov. Všetky súbory zaberajú veľkosť, ktorá je násobkom veľkosti klastra. Aj keď má súbor veľkosť 1 kB a klaster 16 kB, súbor zaberie celých 16 kB.
Bolo by logické robiť malé klastre, ale potom prichádza na rad obmedzenie maximálneho počtu súborov a ich veľkosti. FAT16 pracuje na 16-bitových dátach, takže nemôžete vložiť viac ako 2^16 klastrov. Preto čím je ich veľkosť menšia, tým efektívnejšie sa využíva priestor pre malé súbory, no tým menej informácií sa dá na disk vtesnať. A naopak, čím väčšia je veľkosť, tým viac informácií môžete vtesnať, ale tým menej efektívne sa využíva priestor pre malé súbory. Maximálna veľkosť klastra je 64 kB, takže maximum pre FAT16 je 64 kb*2^16 = 4 GB.
Počiatočné údaje: K dispozícii je 1 GB pamäťová karta micro SD. Označený MYDISK, plne naformátovaný, veľkosť klastra 16kB.
Budete potrebovať Hex editor, ale žiadny editor nebude fungovať; potrebujete taký, ktorý dokáže zobraziť celý disk, nielen súbory na disku. Z toho, čo sa mi podarilo nájsť: WinHex je najvhodnejší, ale platený; HxD je jednoduchý, bezplatný, ale nepodarilo sa mi ho dostať na uloženie zmien na disk; DMDE je trochu neprívetivý, bezplatný a umožňuje ukladať zmeny. Vo všeobecnosti som sa usadil na HxD.
Po prvé, stojí za to zvážiť štruktúru FAT16, obrázok ukazuje, v akom poradí sú umiestnené rôzne časti súborového systému.
Všetky servisné informácie sú uložené v zavádzacom sektore. Oblasť FAT ukladá informácie o umiestnení údajov súboru na disku. Koreňový adresár obsahuje informácie o tom, aké súbory sú v koreňovom adresári disku. Údajová oblasť obsahuje informácie obsiahnuté v súboroch. Všetky plochy na seba striktne nadväzujú v rade, t.j. Po boot sektore okamžite začína oblasť FAT. Pozrime sa na podrobnosti nižšie.
Úloha: pochopiť princíp, podľa ktorého sú usporiadané názvy súborov a ich obsah. Začnime teda prehľadávaním koreňového adresára, aby sme pochopili, aké súbory máme k dispozícii. Pomôžu nám v tom údaje z oblasti batožinového priestoru.
Najzaujímavejšie údaje sú uvedené v tabuľke
Prvá vec, ktorú potrebujeme, je poznať veľkosť batožinového priestoru. Pozrieme sa na adresu 0x0E a vidíme, že pre bootovaciu oblasť sú alokované 4 sektory, t.j. Oblasť FAT začína na adrese 4*512 = 0x800.
Počet tabuliek FAT možno určiť podľa adresy 0x10 bootovacej oblasti. V našom príklade sú dve, prečo dve, pretože každá tabuľka je duplikovaná ako záložná tabuľka, aby sa v prípade zlyhania dali dáta obnoviť. Veľkosť tabuľky je uvedená na adrese 0x16. Veľkosť súboru je teda 512*2*0xEE = 0x3B800 a koreňový adresár začína na adrese: 0x800 + 0x3B800 = 0x3C000
Vo vnútri koreňového adresára sú všetky prvky rozdelené na 32 bajtov. Prvým prvkom je menovka zväzku, ale nasledujúcimi prvkami sú súbory a priečinky. Ak názov súboru začína 0xE5, znamená to, že súbor bol odstránený. Ak názov začína 0x00, znamená to, že predchádzajúci súbor bol posledný.
Prišiel som s pomerne zaujímavou koreňovou adresárovou štruktúrou. Karta bola kompletne naformátovaná, následne boli vytvorené 2 textové súbory, ktoré boli premenované na MyFile.txt a BigFile.txt.
Ako vidno, okrem mojich dvoch spisov sa vytvorila kopa ľavicových, o ktorých pôvode možno len hádať.
Najdôležitejšia vec, ktorú tu možno zdôrazniť, je adresa prvého klastra, od ktorého začínajú údaje nášho súboru. Adresa je vždy umiestnená na ofsete 0x1A. Napríklad názov nášho súboru MyFile.txt sa nachádza na adrese 0x3C100, pridáme k nemu 0x1A, tam vidíme číslo prvého klastra. = 0x0002 t.j. druhý klaster. V prípade súboru BigFile.txt začínajú údaje od tretieho klastra.
V koreňovom adresári nájdete aj dátum a čas poslednej úpravy súboru, táto otázka ma veľmi nezaujímala, takže ju obídem. Posledná užitočná vec, ktorú vám môže koreňový adresár povedať, je jeho veľkosť, aby sme mohli nájsť, kde začínajú dáta.
Veľkosť je uvedená v zavádzacom sektore na adrese 0x11(2bajty) = 0x0200*32 = 0x4000 alebo 16384 bajtov.
Ku koreňovej adrese pripočítajme jeho veľkosť: 3C000 + 4000 = 40000 je adresa prvého dátového klastra, no na nájdenie súboru MyFile.txt potrebujeme druhý. Počet sektorov v klastri je 32, veľkosť klastra = 32*512 = 16384 alebo 0x4000, teda pripočítajme k adrese prvého klastra jeho veľkosť, t.j. Teoreticky by mal druhý klaster začínať na 0x44000.
Ideme na adresu 0x44000 a vidíme, že údaje patria do BigFile.txt (je to len odpad)
Ukazuje sa, že existuje malá jemnosť, číslovanie zhlukov začína od druhého, nie je jasné, prečo sa to stalo, ale je to fakt, t.j. v skutočnosti sme sa presunuli do tretieho klastra. Vráťme sa o jeden klaster späť na adresu 0x40000 a uvidíme očakávané dáta.
Teraz vyvstáva otázka. Prečo potrebujeme tabuľku FAT? Ide o to, že dáta môžu byť fragmentované, t.j. Začiatok súboru môže byť v jednom klastri a koniec v úplne inom. Navyše to môžu byť úplne odlišné klastre. Môže ich byť niekoľko, roztrúsených v rôznych dátových oblastiach. Tabuľka FAT je druh mapy, ktorá nám hovorí, ako sa pohybovať medzi klastrami.
Uveďme príklad: do súboru BigFile.txt sa natlačí kopa náhodného odpadu, takže nezaberá jeden klaster, ale hneď niekoľko. Ideme tam, kde začína tabuľka FAT a pozrieme sa na jej obsah.
Prvých osem bajtov 0xF8FFFFFF je identifikátor pre začiatok tučnej tabuľky. Ďalej sú to 2 bajty, ktoré odkazujú na MyFile.txt, to, že je v nich zapísané 0xFFFF znamená, že súbor zaberá iba jeden klaster. Ale ďalší súbor BigFile.txt začína v treťom klastri, ten si pamätáme z koreňového adresára, pokračuje vo štvrtom, potom ide na 5,6,7... a končí na 12, t.j. zaberá 10 zhlukov.
Preverme si, či je to naozaj tak. Súbor váži 163kB, t.j. zaberá 163000/(32*512) = 9,9 klastrov, čo je dosť podobné tomu, čo sa očakáva. Zopakujme si ešte raz, že jeden prvok v tabuľke FAT zaberá 2 bajty, t.j. 16 bitov, odtiaľ názov FAT16. Podľa toho je maximálna adresa 0xFFFF, t.j. maximálna hlasitosť pre FAT16 0xFFFF*veľkosť klastra.
Prejdime na FAT32. Nakladacia časť bola mierne zmenená.
Sú tu niektoré zásadné zmeny. Názov systému súborov sa presunul na adresu 0x52, koreňová veľkosť sa teraz ignoruje. Údajová oblasť je hneď za tabuľkami FAT, koreňový adresár je vo vnútri dátovej oblasti. Okrem toho koreňový adresár nemá pevnú veľkosť.
Adresa dátovej oblasti sa vypočíta:
veľkosť zavádzacieho sektora + tabuľka FAT, v mojom prípade to dopadlo takto:
746496 + (3821056 * 2) = 0x800000
Adresa koreňového adresára sa vypočíta:
(číslo prvého klastra koreňového adresára - 2) * veľkosť klastra + adresa začiatku dátovej oblasti,
tie. v tomto príklade sa bude zhodovať so začiatkom oblasti údajov.
Rovnako ako predtým, údaje v koreňovom adresári zaberajú 32 bajtov, ako predtým „vymazané“ magické súbory, predpokladám, že ide o dočasné súbory poznámkového bloku.
Začiatok prvého klastra v súbore MYFILE.txt je teraz určený dvoma bajtmi, najvyšším s posunom 0x14, najnižším ako predtým 1A. Preto číslo prvého dátového klastra pre súbor bude:
8000A0 + 0x14 = 0x8000B4 - vysoký bajt
8000A0 + 0x1A = 0x8000BA - nízky bajt
V mojom prípade mala karta iba jeden súbor, takže toto je tretí klaster.
Tabuľka FAT sa prehľadáva ako v predchádzajúcom prípade, len teraz prvky zaberajú 4 bajty, preto názov FAT32. Ideológia usporiadania prvkov je úplne rovnaká ako v predchádzajúcom prípade.
Užitočné veci na stôl
F8 FF FF F0 - prvý klaster
FF FF FF 0F - posledný klaster
FF FF FF F7 - poškodený klaster
Kde sú údaje?
začiatok oblasti údajov + veľkosť klastra * (číslo koreňového klastra - 1)
= 0x800000 + (2*4096) = 0x801000
Dúfam, že vo všeobecnosti sa to vyjasnilo, zdá sa, že neexistuje nič nadprirodzené. Tí, ktorí čítajú a opakujú, môžu jesť koláčik :)
NTFS, FAT alebo exFAT sú úplne odlišné systémy súborov, ktoré možno použiť na ukladanie údajov na rôzne médiá. Obidva boli vytvorené spoločnosťou Microsoft a používajú sa hlavne pre Windows, ale sú podporované aj v jadre Linuxu.
NTFS sa najčastejšie používa na inštaláciu operačného systému Windows alebo oddielov Windows pre súbory, zatiaľ čo FAT sa často používa na flash disky alebo iné externé úložné zariadenia. FAT možno často použiť aj ako hlavný súborový systém pre Android. V tomto článku sa pozrieme na rozdiely medzi FAT a NTFS, podrobne rozoberieme, ako sa líšia a prečo sú potrebné.
Súborový systém stanovuje základné pravidlá, ako budú dáta usporiadané pri zápise na médium, bez ohľadu na to, či ide o pevný disk alebo flash disk. Systém súborov popisuje, ako budú priečinky usporiadané.
Určitý údaj nazývaný súbor sa umiestni do požadovanej oblasti jednotky. Súborový systém vykonáva všetky potrebné výpočty a tiež určuje minimálnu nedeliteľnú veľkosť bloku údajov, maximálnu veľkosť súboru a monitoruje fragmentáciu. Existuje mnoho rôznych typov súborových systémov, ako sú systémy súborov inštalácie OS, systémy súborov externých médií, súborové systémy optických diskov a distribuované súborové systémy. Ale v tomto článku budeme porovnávať len tuk a ntfs.
Čo je súborový systém FAT?
Súborové systémy fat32 a ntfs sú veľmi odlišné. FAT je skratka pre File Allocation Table. Toto je veľmi starý súborový systém v histórii výpočtových systémov. Jeho príbeh sa začal v roku 1977. Potom bol vyvinutý 8-bitový súborový systém, ktorý bol použitý v NCR 7200 založenom na Intel 8080. Bol to vstupný terminál, ktorý pracoval s disketami. Súborový systém napísal zamestnanec Microsoftu Mark McDonald po diskusii o koncepte s Billom Gatesom.
Súborový systém FAT sa potom začal používať v operačnom systéme MDOS pre platformu Z80. O niekoľko rokov neskôr boli vydané nové verzie ako FAT12, FAT16 a FAT32.
FAT32 zvýšil maximálnu veľkosť zväzku na 16 TB v porovnaní s FAT16. Zväčšila sa aj veľkosť súboru na 4 GB. 32bitová tabuľka prideľovania súborov bola vydaná v auguste 1995 pre Windows 95. Tento súborový systém sa však stále nedá použiť na inštaláciu náročných aplikácií alebo ukladanie veľkých súborov. Preto spoločnosť Microsoft vyvinula nový súborový systém - NTFS, ktorý takéto nedostatky nemá.
FAT32 je vynikajúci súborový systém pre externé médiá, ak potrebujete preniesť súbory nie väčšie ako 4 GB. Je podporovaný mnohými rôznymi zariadeniami, ako sú fotoaparáty, fotoaparáty, hudobné prehrávače. Všetky verzie distribúcií Windows a Linux plne podporujú FAT32. Dokonca to podporuje aj Apple MacOS.
Čo je to súborový systém NTFS?
Pre svoje nové systémy Microsoft vyvinul nový súborový systém – New Technology File System alebo NTFS. Objavil sa v roku 1993 vo Windows NT 3.1. NTFS odstránil mnohé obmedzenia týkajúce sa veľkosti súborov a diskov. Jeho vývoj sa začal v roku 1980 ako výsledok zlúčenia spoločností Microsoft a IBM s cieľom vytvoriť nový súborový systém so zlepšeným výkonom.
Spolupráca medzi spoločnosťami však netrvala dlho a IBM vydala HPFS, ktorý bol použitý v OS/2, a Microsoft vytvoril NTFS 1.0. Maximálna veľkosť jedného súboru v NTFS môže dosiahnuť 16 exabajtov, čo znamená, že sa doň zmestia aj tie najväčšie súbory.
NTFS 3.1 bol vydaný pre Windows XP a dostal mnoho zaujímavých vylepšení, ako je podpora pre zmenšenie veľkosti partícií, automatické obnovenie a symbolické odkazy a maximálna veľkosť disku súborového systému bola zvýšená na 256 TB. A to aj napriek maximálnej veľkosti súboru 16 EB.
Medzi ďalšie zaujímavé funkcie, ktoré boli pridané neskôr, patrí lenivý zápis na disk, podpora defragmentácie, nastavenie diskových kvót, sledovanie odkazov a šifrovanie na úrovni súborov. Vďaka tomu všetkému zostáva NTFS kompatibilný s predchádzajúcimi verziami.
Teraz je to žurnálovaný súborový systém, všetky akcie so súbormi sa zaznamenávajú do špeciálneho žurnálu, pomocou ktorého je možné v prípade poškodenia veľmi rýchlo obnoviť súborový systém. Systém NTFS je podporovaný v systéme Windows XP a novších. Ak porovnáme fat alebo ntfs, ten druhý nie je v Linuxe plne podporovaný, zápis a obnovenie v prípade poškodenia je možné, ale v MacOS je podporované iba čítanie.
Čo je súborový systém exFAT?
Súborový systém exFAT je ďalším projektom spoločnosti Microsoft na zlepšenie starého systému súborov. Môže byť pruhovaný tam, kde sa nezmestí FAT32. Je oveľa ľahší ako NTFS, ale podporuje súbory väčšie ako 4 GB a často sa používa aj na flash diskoch a jednotkách. Pri jeho vývoji Microsoft použil svoju technológiu na vyhľadávanie názvov súborov podľa hash, čo výrazne zlepšuje výkon.
Väčšina krajín uznáva patentové právo USA, takže implementácia exFAT nie je možná na žiadnych uzavretých alebo otvorených systémoch. Microsoft však chce, aby bol tento súborový systém voľne distribuovaný a používaný. Preto bola vyvinutá verzia exFAT založená na FUSE s názvom fuse-exfat. Poskytuje úplný prístup na čítanie a zápis. V Samsungu vznikla aj implementácia na úrovni jadra Linuxu, ktorá je už aj verejne dostupná.
Tento súborový systém má tiež maximálny limit veľkosti súboru 16 EB, ale je oveľa ľahší a nemá žiadne ďalšie funkcie. Ak hovoríme o kompatibilite, je plne podporovaná na Windows, MacOS, Android a Linux.
Rozdiely medzi FAT a Ntfs
Teraz sa pozrime na hlavné rozdiely medzi FAT a NTFS vo forme stručného zhrnutia jednotlivých súborových systémov:
FAT32
- Kompatibilita: Windows, Mac, Linux, herné konzoly, takmer všetky zariadenia s USB portom;
- Výhody: multiplatformové, ľahké;
- mínusy: maximálna veľkosť súboru 4 GB a veľkosť oddielu 16 GB, bez žurnálov;
- Použitie: externé médiá.
NTFS
- Kompatibilita: Windows, Linux, Xbox One a iba na čítanie na Macu;
- Výhody:žurnálované, veľké limity na veľkosť oddielu a súboru, šifrovanie, automatické obnovenie;
- mínusy: obmedzená multiplatformová;
- Použitie: na inštaláciu systému Windows.
exFAT
- Kompatibilita: Windows XP a vyšší, MacOS X 10.6.5, Linux (poistka), Android;
- Výhody: veľký limit na veľkosť oddielu a súboru, ľahký v porovnaní s NTFS;
- mínusy: Microsoft obmedzuje jeho použitie na licenčnú zmluvu;
- Použitie: pre externé médiá a externé pevné disky.
závery
V tomto článku sme urobili porovnanie medzi tukmi a ntfs. Ide o veľmi odlišné súborové systémy. Je však ťažké pochopiť, ktorý súborový systém je lepší ako tuk alebo ntfs; na jednej strane má NTFS oveľa viac možností, ale FAT je ľahší a je podporovaný všade, kde je to možné. Pre dátové oddiely v systéme Linux, ktoré musia byť dostupné v systéme Windows, je lepšie použiť FAT namiesto NTFS, pretože je lepšie podporovaný. Čo si myslíte, že je lepšie tuk alebo ntfs pre Linux?
Súborový systém FAT (File Allocation Table) získava svoj názov z jednoduchej tabuľky, ktorá špecifikuje:
Priamo adresovateľné časti logického disku, určené na umiestnenie súborov alebo ich fragmentov do nich;
Voľné oblasti miesta na disku;
Chybné oblasti disku (tieto oblasti obsahujú chybné oblasti a nezaručujú bezchybné čítanie a zápis údajov).
V súborovom systéme FAT je diskový priestor ľubovoľnej logickej jednotky rozdelený na dve oblasti (obr. 6.1): systémová oblasť A dátová oblasť.
Ryža. 6.1. Štruktúra logického disku vo FAT
Systémová oblasť logického disku sa vytvára a inicializuje počas formátovania a následne sa aktualizuje pri práci so štruktúrou súborov. Údajová oblasť logického disku obsahuje bežné súbory a adresárové súbory; tieto objekty tvoria hierarchiu podriadenú koreňovému adresáru. Katalógový prvok
Systém súborov FAT_________________________________________________ 167
ga popisuje objekt súboru, ktorým môže byť buď obyčajný súbor alebo adresárový súbor. Dátová oblasť je na rozdiel od systémovej oblasti prístupná cez používateľské rozhranie operačného systému. Systémová oblasť pozostáva z nasledujúcich komponentov (umiestnených jeden po druhom v priestore logických adries):
Boot Record (BR);
vyhradené sektory (ResSec);
Tabuľka prideľovania súborov (FAT);
Koreňový adresár (RDir).
Tabuľka prideľovania súborov
Alokačná tabuľka súborov je veľmi dôležitá informačná štruktúra. Dá sa povedať, že ide o mapu adries dátovej oblasti, ktorá popisuje stav každej sekcie dátovej oblasti a jej príslušnosť ku konkrétnemu súborovému objektu.
Celá dátová oblasť je rozdelená na tzv klastre. Klaster je jeden alebo viacero susediacich sektorov v adresnom priestore logického disku (presnejšie len v dátovej oblasti). Klaster je najmenšia adresovateľná jednotka diskovej pamäte pridelená súboru (alebo nekoreňovému adresáru). Klastre sa zavádzajú s cieľom znížiť počet adresovateľných jednotiek v dátovej oblasti logického disku.
Každý súbor zaberá celý počet klastrov. V tomto prípade nemusí byť posledný klaster plne využitý, čo pri veľkej veľkosti klastra môže viesť k citeľnej strate miesta na disku. Na disketách klaster zaberá jeden alebo dva sektory a na pevných diskoch jeho veľkosť závisí od veľkosti partície (tabuľka 6.1). V tabuľke FAT sú klastre patriace do rovnakého súboru (alebo adresárového súboru) spojené do reťazcov. Súborový systém FAT 16 používa 16-bitové slovo na určenie čísla klastra, takže môžete mať až 2 10 = 65 536 klastrov (očíslovaných od 0 do 65 535).
Tabuľka 6.1. Vzťah medzi veľkosťou oddielu a veľkosťou klastra v systéme FAT16
Kapacita oddielu, MB Počet sektorov v klastri Veľkosť klastra, KB
Všimnite si, že vo Windows NT/2000/XP môžu mať oddiely systému súborov FAT veľkosť až 4097 MB. V tomto prípade bude klaster združovať už 128 sektorov.
Číslo klastra vždy odkazuje na dátovú oblasť disku (priestor vyhradený pre súbory a podadresáre). Čísla zhlukov zodpovedajú prvkom
168___________________________________________________________ Kapitola 6, Systémy súborov
alokačnej tabuľky súborov. Prvé platné číslo klastra vždy začína 2.
Logické rozdelenie oblasti údajov na klastre ako kolekciu sektorov namiesto použitia jednotlivých sektorov má nasledujúci význam:
V prvom rade je zmenšená veľkosť samotnej tabuľky FAT; - je znížená možná fragmentácia súborov;
Prístup k súboru sa zrýchli, pretože dĺžka reťazcov fragmentov miesta na disku, ktoré mu boli pridelené, sa niekoľkokrát zníži.
Príliš veľká veľkosť klastra však vedie k neefektívnemu využívaniu dátovej oblasti, najmä v prípade veľkého množstva malých súborov. Ako sme si práve všimli, v priemere sa stratí asi polovica klastra na súbor. Od stola 6.1 vyplýva, že pri veľkosti klastra 32 sektorov (objem oddielu je od 512 do 1023 MB), teda 16 KB, je priemerná strata na súbor 8 KB a pri niekoľkých tisícoch súborov môže byť 1 strata viac. ako 100 MB. Preto sú v moderných súborových systémoch veľkosti klastrov obmedzené (zvyčajne od 512 bajtov do 4 KB), alebo je poskytovaná možnosť zvoliť si veľkosť klastra.
Myšlienka súborového systému s použitím tabuľky prideľovania súborov je celkom jasne znázornená na obr. 6.2.
Ryža. 6.2. Ilustrácia základného konceptu FAT
Obrázok ukazuje, že súbor MYFILE.TXT sa nachádza od ôsmeho klastra. Celkovo súbor MYFILE.TXT zaberá 12 klastrov. Reťazec zhlukov pre náš príklad možno zapísať takto: 8, 9.0A, 0B, 15,16,17,19,
1 Napríklad počet 10 000 – 15 000 súborov (alebo dokonca viac, najmä ak sú súbory malé) na 1 000 MB logickej jednotke je celkom bežný.
Súborový systém FAT169
1A, 1B, 1C, 1D. Klaster číslo 18 je označený špeciálnym kódom F7 ako zlý a nemožno ho použiť na hosťovanie údajov. Pri formátovaní sa zvyčajne kontroluje povrch magnetického disku a tie sektory, z ktorých sa pri testovacom čítaní vyskytli chyby, sú označené vo FAT ako zlé. Klaster 1D je označený kódom FF ako posledný (posledný v reťazci) klaster patriaci do tohto súboru. Voľné (neobsadené) zhluky sú označené kódom 00; Keď je na zapisovanie súboru pridelený nový klaster, zaberie sa prvý voľný klaster. Možné hodnoty, ktoré možno priradiť prvkom tabuľky FAT, sú uvedené v tabuľke. 6.2.
Tabuľka 6.2. hodnoty prvkov FAT
Popis hodnoty
OOOOh Voľný klaster
fffOh-fff6h Vyhradený klaster
fff7h Zlý klaster
fffSh-ffffh Posledný zhluk v reťazci
0002h-ffefh Číslo nasledujúceho klastra v reťazci
Keďže sa súbory na disku menia (odstraňujú, presúvajú, zväčšujú alebo zmenšujú), spomínané pravidlo pridelenia prvého voľného klastra pre novú časť dát vedie k fragmentácia to znamená, že údaje jedného súboru sa nemusia nachádzať v susedných zhlukoch, ale niekedy vo veľmi vzdialených zhlukoch, ktoré tvoria zložité reťazce. Prirodzene to vedie k výraznému spomaleniu práce so súbormi.
Keďže pri prístupe na disk sa tabuľka FAT používa veľmi intenzívne, zvyčajne sa načíta do RAM (v I/O bufferoch alebo cache) a zostane tam čo najdlhšie. Ak je tabuľka veľká a vyrovnávacia pamäť súborov relatívne malá, do pamäte sa uložia len naposledy prístupné fragmenty tabuľky.
Kvôli mimoriadnej dôležitosti tabuľky FAT sa zvyčajne ukladá v dvoch identických kópiách, z ktorých druhá bezprostredne nasleduje za prvou. Kópie FAT sa aktualizujú súčasne, ale používa sa iba prvá kópia. Ak sa z nejakého dôvodu ukáže, že je zničená, bude kontaktovaná druhá kópia. Napríklad utilita ScanDisk na kontrolu a obnovu štruktúry súborov z OS Windows 9x, keď zistí nesúlad medzi primárnou a FAT záložnou kópiou, ponúkne obnovenie hlavnej tabuľky pomocou údajov z kópie.
Koreňový adresár sa líši od bežného adresárového súboru tým, že okrem toho, že je umiestnený na pevnom mieste na logickom disku, má aj pevný počet prvkov. Pre každý súbor a adresár sú informácie uložené v súborovom systéme v súlade so štruktúrou uvedenou v tabuľke. 6.3.
Na prácu s údajmi na magnetických diskoch v systémoch DOS, ktoré majú súborový systém FAT, je vhodné použiť známy nástroj Disk Editor z
170___________________________________________ Kapitola 6. Systémy súborov
Úžitková súprava Petra Nortona. Má veľa výhod. Predovšetkým je kompaktný, ľahko sa umiestni na systémovú disketu s MS DOS a je vybavený vstavaným systémom tipov a potrebnými referenčnými informáciami. Pomocou neho môžete uložiť, upraviť a obnoviť zavádzací záznam, obnoviť tabuľku FAT, ak je poškodená, a tiež vykonávať mnoho ďalších operácií. Hlavnými nevýhodami tohto programu sú dnes obmedzenia veľkosti diskov a oddielov a nedostatočná podpora pre prácu s takými bežnými súborovými systémami, ako sú FAT32 a NTFS. Namiesto toho sa teraz často používa utilita Partition Magic, ale za najlepšiu alternatívu k tomuto programu dnes možno považovať utilitu Disk Administrator od Acronis.
Tabuľka 6.3.Štruktúra položky katalógu
Veľkosť dátového poľa, bajty Obsah poľa
11 Názov súboru alebo adresára
1 Atribúty súboru
1 Rezervné pole
3 Čas vytvorenia
2 Dátum vytvorenia
2 Dátum posledného prístupu
2 Vyhradené
2 Čas poslednej úpravy
2 Dátum poslednej úpravy
2 Počiatočné číslo klastra vo FAT
4 Veľkosť súboru
Štruktúra zavádzacieho záznamu DOS
Sektor obsahujúci zavádzač systému DOS je úplne prvým sektorom na logickej jednotke C:. Pripomeňme, že na diskete je zavádzač systému umiestnený v prvom sektore; jeho fyzická adresa je 0-0-1. Ako už vieme, bootovací záznam pozostáva z dvoch častí: blok parametrov disku(Blok parametrov disku, DPB) a zavádzač(System Bootstrap, SB). Blok možností disku slúži na identifikáciu fyzických a logických formátov logického disku a zavádzač systému hrá významnú úlohu v procese zavádzania systému DOS. Táto informačná štruktúra je uvedená v tabuľke. 6.4.
Prvé dva bajty zavádzacieho záznamu sú obsadené inštrukciou nepodmieneného skoku (JMP) do programu SB. Tretí bajt obsahuje kód 90H (NOP - bez operácie). Ďalej je osembajtový systémový identifikátor, ktorý obsahuje informácie o vývojárovi a verzii operačného systému. Nasleduje blok parametrov disku a po ňom príde na rad bootloader systému.
Na prácu so zavádzacím záznamom DOS, ako aj s inými štruktúrami servisných informácií je vhodné použiť už spomínaný program Disk
Systém súborov FAT_________________________________________________ 171
Editor zo sady nástrojov Petra Nortona. Pomocou neho môžete uložiť, upraviť a obnoviť zavádzací záznam, ako aj vykonávať mnoho ďalších operácií. Práca s týmto nástrojom je dostatočne podrobne popísaná v.
Tabuľka 6.4. Štruktúra zavádzacieho záznamu pre FAT16
Offset poľa, dĺžka poľa, obsah poľa označenia
bajt pole bajt
UN (0) 3 SKOK 3EH Bezpodmienečný skok na štart
zavádzač
OZN (3) 8 ID systému
OVN (11) 2 SectSize Veľkosť sektora, bajty
UN (13) 1 ClastSize Počet sektorov v klastri
0EN(14) 2 ResSecs Počet vyhradených sektorov
10Н (16) 1 FATcnt Počet kópií FAT
11Н (17) 2 RootSize Maximálny počet prvkov Rdir
13H (19) 2 TotSecs Počet sektorov na logickom disku,
ak jeho veľkosť nepresahuje 32 MB; inak 0000H
15H (21) 1 Médiá Popis média
16Н(22) 2 FATsize Veľkosť FAT, sektory
18Н(24) 2 TrkSecs Počet sektorov na stopu
1АН(26) 2 HeadCnt Počet pracovných plôch
1СН(28) 4 HidnSecs Počet skrytých sektorov
20H (32) 4 Počet sektorov na logickom disku,
ak jeho veľkosť presahuje 32 MB
24H (36) 1 Typ logického disku (UN - flexibilný,
80N - tvrdý)
25Н (37) 1 Vyhradené
26Н (38) 1 popisovač s kódom 29Н
27Н (39) 4 Poradové číslo zväzku 1
2 ВН (43) 11 Označenie zväzku
36Н (54) 8 Názov systému súborov
ZEN (62) Bootloader
1FEH (510) 2 Podpis (slovo AA55Н)
1 Zväzok je jediný logický adresný priestor. Zväzok môže byť bežný logický disk alebo viacero diskových priestorov.