FAT32文件系統實踐

== FAT32 ==
FAT32文件系統有本身的格式,其中比較重要的概念包括:
=== MBR ===
MBR(master boot record),即主引導記錄,有時也稱主引導扇區。位於整個硬盤的0柱面0磁頭1扇區(能夠看做是硬盤的第一個扇區),bios在執行本身固有的程序之後就會jump到mbr中的第一條指令(<font color=red>在咱們的操做中BIOS負責LOAD內核,而且跳轉到內核加載地址,並不涉及硬盤的MBR,MBR可能與GRUB有關</font>)。將系統的控制權交由mbr來執行。在總共512byte的主引導記錄中,MBR的引導程序佔了其中的前446個字 節(偏移0H~偏移1BDH),隨後的64個字節(偏移1BEH~偏移1FDH)爲DPT(Disk PartitionTable,硬盤分區表),最後的兩個字節「55 AA」(偏移1FEH~偏移1FFH)是分區有效結束標誌。


在Linux下使用dd命令得到MBR
 root@llc-loongson:~# fdisk -l
 
 Disk /dev/sda: 160.0 GB, 160041885696 bytes
 255 heads, 63 sectors/track, 19457 cylinders
 Units = cylinders of 16065 * 512 = 8225280 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
 I/O size (minimum/optimal): 512 bytes / 512 bytes
 Disk identifier: 0xe467e467
 
    Device Boot      Start         End      Blocks   Id  System
 /dev/sda1   *           1        3901    31334751    c  W95 FAT32 (LBA)
 /dev/sda2            3902        9125    41961780    7  HPFS/NTFS
 /dev/sda3            9126       17001    63263970    7  HPFS/NTFS
 /dev/sda4           17002       19458    19729409    5  Extended
 /dev/sda5           17002       19215    17776640   83  Linux
 /dev/sda6           19215       19458     1951744   82  Linux swap / Solaris
 root@llc-loongson:~# dd if=/dev/sda of=./MBR count=1 bs=512
 記錄了1+0 的讀入
 記錄了1+0 的寫出
 512字節(512 B)已複製,0.000296544 秒,1.7 MB/秒
而後使用vim查看MBR
 root@llc-loongson:~# vim MBR
在vim中使用底行模式
 :%!xxd查看二進制
因爲前446字節爲引導程序,從1BEH開始爲DPT(分區表)
 00001b0: cd10 ac3c 0075 f4c3 67e4 67e4 0000 8001  ...<.u..g.g.....
 00001c0: 0100 0cfe ffff 3f00 0000 be42 bc03 0000  ......?....B....
 00001d0: c1ff 07fe ffff fd42 bc03 6892 0005 0000  .......B..h.....
 00001e0: c1ff 07fe ffff 65d5 bc08 c4a9 8a07 00fe  ......e.........
 00001f0: ffff 05fe ffff fe7f 4710 0218 5a02 55aa  ........G...Z.U.
 字節位移 字段長度  值    字段名和定義
 0x01BE         BYTE 0x80    引導指示符(Boot Indicator)   指明該分區是不是活動分區。(0x80表示活動,0x00表示非活動)
 0x01BF         BYTE 0x01    開始磁頭(Starting Head)
 0x01C0         6位 0x01             開始扇區(Starting Sector) 只用了0~5位。後面的兩位(第6位和第7位)被開始柱面字段所使用
 0x01C1        10位 0x00             開始柱面(Starting Cylinder)   除了開始扇區字段的最後兩位外,還使用了1位來組成該柱面值。開始柱面是一個10位數,最大值爲1023
 0x01C2        BYTE 0x0c    系統ID(System ID) 定義了分區的類型,詳細定義,請參閱圖4
 0x01C3  BYTE  0xFE    結束磁頭(Ending Head)
 0x01C4  6位  0xFF             結束扇區(Ending Sector)     只使用了0~5位。最後兩位(第六、7位)被結束柱面字段所使用
 0x01C5  10位  0x1FF    結束柱面(Ending Cylinder) 除告終束扇區字段最後的兩位外,還使用了1位,以組成該柱面值。結束柱面是一個10位的數,最大值爲1023
 0x01C6  DWORD 0x0000003F  相對扇區數(Relative Sectors) 從該磁盤的開始到該分區的開始的位移量,以扇區來計算
 0x01CA  DWORD 0x03BC42BE  總扇區數(Total Sectors) 該分區中的扇區總數 
因爲分區表只能表示4個分區,因此分區表中最後的分區是擴展分區的統一表示。
擴展分區
擴展分區中的每一個邏輯驅動器都存在一個相似於MBR的擴展引導記錄( Extended Boot Record, EBR),也有人稱之爲虛擬mbr或擴展mbr,意思是同樣的。擴展引導記錄包括一個擴展分區表和該扇區的標籤。擴展引導記錄將記錄只包含擴展分區中每一個邏輯驅動器的第一個柱面的第一面的信息。一個邏輯驅動器中的引導扇區通常位於相對扇區32或63。可是,若是磁盤上沒有擴展分區,那麼就不會有擴展引導記錄和邏輯驅動器。第一個邏輯驅動器的擴展分區表中的第一項指向它自身的引導扇區。第二項指向下一個邏輯驅動器的EBR。若是不存在進一步的邏輯驅動器,第二項就不會使用,並且被記錄成一系列零。若是有附加的邏輯驅動器,那麼第二個邏輯驅動器的擴展分區表的第一項會指向它自己的引導扇區。第二個邏輯驅動器的 擴展分區表的第二項指向下一個邏輯驅動器的EBR。擴展分區表的第三項和第四項永遠都不會被使用。
=== DBR ===
每個分區的起始扇區爲DBR區,在這512個字節中,其實又是由跳轉指令,廠商標誌和操做系統版本號,BPB(BIOS Parameter Block),擴展BPB,os引導程序,結束標誌幾部分組成。跳轉指令是爲了引導系統,引導過程當中MBR會將CPU引導過來,這裏不關注。從偏移0x0B開始的是一段描述可以使可執行引導代碼找到相關參數的信息。一般稱之爲BPB(BIOS Parameter Block),BPB通常開始於相同的位移量,所以,標準的參數都處於一個已知的位置。磁盤容量和幾何結構變量都被封在BPB之中。
使用dd命令獲得分區的DBR
 root@llc-loongson:~# dd if=/dev/sda1 of=./DBR bs=512 count=1
查看二進制獲得BPB
 0000000: eb58 904d 5344 4f53 352e 3000 0220 2600  .X.MSDOS5.0.. &.
 0000010: 0200 0000 00f8 0000 3f00 ff00 3f00 0000  ........?...?...
 0000020: a042 bc03 bd3b 0000 0000 0000 0200 0000  .B...;..........
 0000030: 0100 0600 0000 0000 0000 0000 0000 0000  ................
 0000040: 8000 29f3 576c 744e 4f20 4e41 4d45 2020  ..).WltNO NAME  
 位移 字段長度(字節)  對應取值 名稱和定義
 0x0B 2         0x0200 扇區字節數(Bytes Per Sector) 硬件扇區的大小。
 0x0D 1         0x20 每簇扇區數(Sectors Per Cluster),一簇中的扇區數。
 <font color=red>0x0e 2        0x0026 保留扇區數(Reserved Sector) 第一個FAT開始以前的扇區數,包括引導扇區。</font>
 0x10 1         0x02 FAT數(Number of FAT) 該分區上FAT的副本數。本字段的值通常爲2
 0x11 2         0x0000 根目錄項數(Root Entries)只有FAT12/FAT16使用此字段。對FAT32分區而言,本字段必須設置爲 0
 0x13 2         0x0000 小扇區數(Small Sector)(只有FAT12/FAT16使用此字段)對FAT32分區而言,本字段必須設置爲0
 0x15 1         0xF8 媒體描述符( Media Descriptor)提供有關媒體被使用的信息。值0xF8表示硬盤,0xF0表示高密度的3.5寸軟盤。
 0x16 2         0x0000 每FAT扇區數(Sectors Per FAT)只被FAT12/FAT16所使用,對FAT32分區而言,本字段必須設置爲0
 0x18 2         0x003F 每道扇區數(Sectors Per Track)
 0x1A 2         0x00FF 磁頭數(Number of Head)
 0x1C 4         0x003F 隱藏扇區數(Hidden Sector) 該分區上引導扇區以前的扇區數。在引導序列計算到根目錄的數據區的絕對位移的過程當中使用了該值。
 0x20 4         0x03bc42a0 總扇區數(Large Sector) 本字段包含FAT32分區中總的扇區數
 <font color=red>0x24 4        0x00003bbd 每FAT扇區數(Sectors Per FAT)(只被FAT32使用)該分區每一個FAT所佔的扇區數。</font>
 0x28 2         0x00 擴展標誌(Extended Flag)
 0x2A 2         0x0000 文件系統版本(File ystem Version)只供FAT32使用,高字節是主要的修訂號,而低字節是次要的修訂號。
 0x2C 4         0x00000002 根目錄簇號(Root Cluster Number)(只供FAT32使用) 根目錄第一簇的簇號。本字段的值通常爲2,但不老是如此
 0x30 2         0x0001 文件系統信息扇區號(File System Information SectorNumber)(只供FAT32使用) 
 0x32 2         0x0006 備份引導扇區(只供FAT32使用)
 0x34 12  12個字節均爲0x00 保留(只供FAT32使用)供之後擴充使用的保留空間。本字段的值總爲0
=== 尋找原理 ===
硬盤分區結構
引導扇區 其他保留扇區 FAT1 FAT2(重複的) 根文件夾首簇 其餘文件夾及全部文件 剩餘扇區
1扇區
實際狀況取大小 同FAT1 第2簇 不足一簇
保留扇區 ┗━━━━━━━━數據區━━━━━━━━┛


先介紹簇的概念:
簇能夠表示成扇區的集合,以簇爲單位而不以扇區爲單位進行磁盤的分配,是由於當分區容量較大時,採用大小爲512B的扇區管理會增長fat表的項數,對大文件存取增長消耗,文件系統效率不高。分區的大小和簇的取值是有關係的。咱們不關心。
FAT爲文件鏈表,以簇爲單位。FAT32文件系統都是從根目錄進行尋找。
下面用一個實際的例子進行演練:
根據DBR信息,找出第一個FAT前的扇區數與FAT所佔的分區數。根據上面的信息我就可以使用:
 dd if=/dev/sda1 of=./ROOT skip=38 count=15293 bs=512
獲得FAT表,FAT表表示文件之間的連接關係,特別是一個大文件不能在一個簇裏面存下,用FAT表能夠將一個文件鏈起來
 0000000: f8ff ff0f ffff ffff ffff ff0f ffff ff0f  ................
 0000010: 1000 0000 ffff ff0f 3d0f 0400 ffff ff0f  ........=.......
 0000020: ffff ff0f 410f 0400 ffff ff0f ffff ff0f  ....A...........
 0000030: 440f 0400 ffff ff0f 6611 0400 ffff ff0f  D.......f.......
 0000040: fb01 0000 0000 0000 ffff ff0f 1800 0000  ................
 0000050: ffff ff0f ffff ff0f e6e9 0000 ffff ff0f  ................
 0000060: d700 0000 1a00 0000 1b00 0000 1c00 0000  ................
 0000070: 1d00 0000 1e00 0000 1f00 0000 2000 0000  ............ ...
 0000080: ffff ff0f 2200 0000 2300 0000 2400 0000  ...."...#...$...
 0000090: 2500 0000 2600 0000 2700 0000 2800 0000  %...&...'...(...
 00000a0: ffff ff0f 2a00 0000 2b00 0000 2c00 0000  ....*...+...,...
 00000b0: 2d00 0000 2e00 0000 2f00 0000 3000 0000  -......./...0...
 00000c0: ffff ff0f ffff ff0f ffff ff0f ffff ff0f  ................
 00000d0: ffff ff0f ffff ff0f ffff ff0f ffff ff0f  ................
 00000e0: ffff ff0f ffff ff0f ffff ff0f ffff ff0f  ................
 00000f0: ffff ff0f ffff ff0f 5ae4 0000 5900 0000  ........Z...Y...
 0000100: ffff ff0f 4c00 0000 ffff ff0f ffff ff0f  ....L...........
 0000110: ffff ff0f ffff ff0f ffff ff0f ffff ff0f  ................
前8字節爲介質描述不關注,偏移0x8--0xb爲0fffffff表示本文件只佔用了一簇。0x85--0x88爲00000022表示本文件的下一個簇在22號簇咱們再去10號簇即偏移0x88--0x8b(計算簇號的時候使用16進制)依次類推22->23->24...->28->29結束。
有了文件連接表,咱們還須要根文件夾。
使用:
 dd if=/dev/sda1 of=./ROOT skip=30624 count=32 bs=512
獲得根文件目錄。
介紹短文件名與長文件名:
 字節偏移     字節數  定義
 0x0~0x7       8 文件名
 0x8~0xA       3 擴展名
 0xB*       1  屬性字節 00000000(讀寫)
                        00000001(只讀)
                        00000010(隱藏)
                        00000100(系統)
                        00001000(卷標)
                        00010000(子目錄)
                        00100000(歸檔)
 0xC        1  系統保留
 0xD        1  建立時間的10毫秒位
 0xE~0xF        2 文件建立時間
 0x10~0x11 2  文件建立日期
 0x12~0x13 2  文件最後訪問日期
 0x14~0x15 2  文件起始簇號的高16位
 0x16~0x17 2  文件的最近修改時間
 0x18~0x19 2  文件的最近修改日期
 0x1A~0x1B 2  文件起始簇號的低16位
 0x1C~0x1F 4  表示文件的長度
咱們截取兩端典型
  53 0000340: 4167 007a 0072 006f 006d 000f 00aa 2e00  Ag.z.r.o.m......
  54 0000350: 6200 6900 6e00 0000 ffff 0000 ffff ffff  b.i.n...........
  55 0000360: 475a 524f 4d20 2020 4249 4e20 0000 5960  GZROM   BIN ..Y`
  56 0000370: 1241 1241 0000 5960 1241 46e7 77e2 1e00  .A.A..Y`.AF.w...
能夠看出它的起始簇號爲0000 e746而後咱們就去FAT表尋找,注意FAT表裏面字節順序。咱們能夠計算出位置,或者直接搜索47e7 0000(存放下一個簇號),經過一簇中的扇區數咱們就能找到數據了。
開始簇號(0xe746 - 2(根目錄從第二簇開始))*0x20(每簇扇區數) + FAT扇區*2 + 保留扇區
在sda1裏面咱們有一個gzrom.bin的文件,從名字長度上看應該屬於一個短文件名,可是讀出的是長文件名,下面的
 457 0001c80: 4455 4f4d 4920 2020 2020 2012 0835 e491  DUOMI      ..5..
 458 0001c90: b240 b240 0800 e591 b240 175b 0000 0000  .@. @..... @.[....
duomi文件夾是短文件,其中的區別在於...懷疑是不一樣的程序或者系統在對文件名的操做不一樣。
長文件名的處理上會截斷13個字符
  11 00000a0: 4220 0053 0065 0074 0074 000f 004a 6900  B .S.e.t.t...Ji.
  12 00000b0: 6e00 6700 7300 0000 ffff 0000 ffff ffff  n.g.s...........
  13 00000c0: 0144 006f 0063 0075 006d 000f 004a 6500  .D.o.c.u.m...Je.
  14 00000d0: 6e00 7400 7300 2000 6100 0000 6e00 6400  n.t.s. .a...n.d.
  15 00000e0: 444f 4355 4d45 7e31 2020 2010 004c a97a  DOCUME~1   ..L.z
  16 00000f0: 233d ec40 0000 aa7a 233d 09cc 0000 0000  #=.@...z#=......
Documents and Settings,從and處截斷,緊隨長文件名的是其對應的短文件名,其中包括起始簇號。
經過讀取根目錄咱們知道了文件的起始簇號,就能夠在FAT表中找到其數據區的鏈表。咱們就不查看了,至於子目錄,子目錄裏面存放的是其下目錄項
  1 0000000: 2e20 2020 2020 2020 2020 2010 0035 e491  .          ..5..
  2 0000010: b240 b240 0800 e591 b240 175b 0000 0000  .@. @..... @.[....
  3 0000020: 2e2e 2020 2020 2020 2020 2010 0035 e491  ..         ..5..
  4 0000030: b240 b240 0000 e591 b240 0000 0000 0000  .@. @..... @......
  5 0000040: 4341 4348 4520 2020 4441 5422 1838 e491  CACHE   DAT".8..
  6 0000050: b240 0441 0800 4c6c 0441 905c 0060 5209  .@.A..Ll.A.\.`R.
  7 0000060: 5245 4144 4d45 2020 5458 5420 1838 e491  README  TXT .8..
  8 0000070: b240 b240 0800 e591 b240 185b ba00 0000  .@. @..... @.[....
duomi的數據區。FAT32文件系統實踐
相關文章
相關標籤/搜索