閱讀385 返回首頁    go 阿裏雲 go 技術社區[雲棲]


解析FAT16文件係統

引導扇區的信息如下:



點擊看大圖 


1.  偏移地址00H,長度3,內容:EB 3C 90 跳轉指令。


2.  偏移地址03H,長度8,內容:4D 53 44 4F 53 35 2E 30 為廠商標誌和os 版本號,這裏是MSDOS5.0。


3.  偏移地址0BH,長度2,內容:00 02。注意這裏數據的布局,高地址放高字節,低地址放低字節(數據為小端格式組織),所以數據應該是0200,即512。表示的意思是,該磁盤每個扇區有512個字節。有的可能是1024、2048、4096。


4.  偏移地址0DH,長度1,內容:01。表示的意思是每個簇有1個扇區。這個值不能為0,而且必須是2的整數次方,比如1、2、4、8、16、32、64、128。但是這個值不能使每個簇超過32KB字節。


5.  偏移地址0EH,長度2,內容:08 00。轉換一下,就是00 08,意思是保留區域中的保留扇區數為8個。那麼就可以知道下麵的FAT1區的開始的地址就是:0x08*0x200(每個扇區的字節數)=0x1000。


6.  偏移地址10H,長度1,內容:02。表示此卷中的FAT結構的份數為2,另外一個是備份的。


7.  偏移地址11H,長度2,內容:00 02。轉換一下,就是0200H,表示根目錄項數(Root Entries) 能夠保存在該分區的根目錄文件夾中的32個字節長的文件和文件夾名稱項的總數。在一個典型的硬盤上,本字段的值為512。


8.  偏移量地址13H,長度2,內容:4D ED。轉換一下就是ED4DH,即大約32MB的SD卡存儲量。表示小扇區數(Small Sector) 。該分區上的扇區數,表示為16位(<65536)。對大於65536個扇區的分區來說,本字段的值為0,而使用大扇區數來取代它。


9.  偏移地址16H,長度2,內容:EC 00。轉換一下為00EC,表示每個FAT占用的扇區數。那麼每個扇區占用的字節數就是0x00EC*0x200=0x1D800。根據啟動區、FAT1、FAT2、根目錄、數據區的次序,可以依次計算出它們的地址了。(教程中給出的偏移地址為24H,但是根據實際的FAT1/FAT2地址的推算,應該是16H地址)


10. 偏移量地址20H,長度2,內容:00 00。表示大扇區數(Large Sector) 。如果小扇區數字段的值為0,本字段就包含該FAT16分區中的總扇區數。如果小扇區數字段的值不為0,那麼本字段的值為0。


11. 偏移量地址36H,長度為8,內容:46 41 54 31 36 20 20 20,對於ASCII碼為“FAT16”,表示文件係統類型(File System Type) 根據該磁盤格式,該字段的值可以為FAT、FAT12或FAT16


啟動區:理所當然是0x00;


FAT1:0x1000;


FAT2:0x1000 + 0x1D800 = 0x1E800;


根目錄區:0x1E800 + 0x1D800 = 0x3C000;


數據區的地址,等等再計算。這個隻是計算,可以看看是不是和實際的一致。

 

點擊看大圖


 


點擊看大圖


 


點擊看大圖 



怎麼樣,是不是和計算的很一致。


為什麼要計算SD數據的讀取要給出地址,而且每次讀取都是一個整扇區,512個字節。找出這些地址後,可以很方便的找到數據。


 現在分析下根目錄區的內容:

點擊看大圖


 

這裏使用的是FAT16短文件目錄項,每32個字節表示一個文件(文件夾也是),32個字節的表示定義分別如下:





FAT16目錄項32個字節的表示定義


字節偏移(16進製)


字節數


定義


0x0~0x7


8


文件名


0x8~0xA


3


擴展名


0xB


1


屬性字節


00000000(讀寫)


00000001(隻讀)


00000010(隱藏)


00000100(係統)


00001000(卷標)


  00010000(子目錄)


00100000(歸檔)


0xC~0x15


10


係統保留


0x16~0x17


2


文件的最近修改時間


0x18~0x19


2


文件的最近修改日期


0x1A~0x1B


2


表示文件的首簇號


0x1C~0x1F


4


表示文件的長度


 


1.  偏移地址00H,長度8,內容:驅動器的名稱,8個字節。這裏的CCD8對應國標碼“特”,而C8A8對應國標碼“權”,即特權同學給該SD卡起的“特權”一名。


2.  偏移地址20H,長度8,內容:54 45 53 54 20 20 20 20。表示第一個文件名:TEST (空缺部分是空格)。


偏移地址80H,長度8,內容:4E 45 58 54 20 20 20 20。表示第二個文件名:NEXT (空缺部分是空格)。


3.  偏移地址28H(88H也一樣),長度3,內容:54 58 54。表示文件類型,為ASCII字符表示。


4.  偏移地址2BH(8BH也一樣),長度1,內容:20。表示文件屬性,00000000(讀寫);00000001(隻讀);00000010(隱藏);00000100(係統);00001000(卷標);00010000(子目錄);00100000(歸檔)。


5.  偏移地址36H,長度2,內容為BA 49。表示時間=小時*2048+分鍾*32+秒/2。得出的結果換算成16進製填入即可。也就是:36H字節的0~4位是以2秒為單位的量值;36H字節的5~7位和37H字節的0~2位是分鍾;37H字節的3~7位是小時。


6.  偏移地址38H,長度2,內容為A3 3A。表示日期=(年份-1980)*512+月份*32+日。得出的結果換算成16進製填入即可。也就是:38H字節0~4位是日期數;38H字節5~7位和39H字節0位是月份;39H字節的1~7位為年號,原定義中0~119分別代表1980~2099,目前高版本的Windows允許取0~127,即年號最大可以到2107年。


7.  偏移地址3AH,長度2,為該文件開始簇號,這裏也是用了小端格式組織。轉換下為00 02,根據這個就可以找到文件TEST.txt下一個簇號在FAT1中的位置了。1000H+02H*02H(因為2個字節存一個簇號)= 1004H。


偏移地址3AH,長度2,為該文件開始簇號,這裏也是用了小端格式組織。轉換下為00 62,根據這個就可以找到文件NEXT.txt下一個簇號在FAT1中的位置了。1000H+62H*02H(因為2個字節存一個簇號)= 10C4H。


8.  偏移地址3CH,長度4,內容:59 BE 00 00。表示文件長度,轉換後為00 00 BE 59就是48729字節。


偏移地址9CH,長度4,內容:32 00 00 00。表示文件長度,轉換後為00 00 00 32就是50字節。


 點擊看大圖 


TEST.txt占用了48KB的空間,NEXT占用了512B的空間。文件是按照整簇來存放的,不夠一個簇的大小(由上麵算得,一個簇為一個扇區即512B),也要給一個簇的空間。


 計算出該文件放置空間。


從文件的大小可以計算出,需要占用多少個簇。根據前麵的數據,每個簇放1個扇區,每個扇區512個字節,那麼一個簇的空間就是512字節了。那麼48729字節需要96個簇,這96個簇的開始的地址就可以計算出來了。


點擊看大圖


 


    首先要提一點,這個地方也是特權同學找了很多資料才發現的,就是根目錄中根文件夾占有32(20H)個扇區應該是固定的(至少對於FAT16應該是這樣),所以真正的用戶數據存放應該是從根目錄地址的32個扇區偏移量後開始算的。


上麵已經知道TEST.txt開始簇地址存放在FAT1中的偏移量了:02H,由此可以先計算出TEST.txt的第一簇數據存放地址為:3C000H(根目錄地址)+20H*200H(前麵提到的用戶數據偏移量)+(02H-02H)*01H(1個簇有1個扇區)*200H=40000H。把偏移量-02H意思是簇號在FAT1中存儲都是從02H開始的。


而第一個簇地址存放在FAT1中的:1000H(FAT1起始地址)+02H*02H=1004H。而1004H地址上的數據為:03 00,轉換後為0003H,那麼我們可以計算出TEST.txt第二個簇的地址為:3C000H(根目錄區地址)+20H*200H(前麵提到的用戶數據偏移量)+ (03H-02H)*01H(1個簇有1個扇區)*200H=40200(第一個簇開始地址)。依此類推,一直到FAT1中偏移量為C2處出現了FF FF,這表示TEST.txt文件存儲結束,那麼前麵的0061H就是文件最後一個簇偏移量。我們可以由此算一下文件大小為:(0061H-0002H+0001H(補償))=96個簇,和實際相符。


    同樣的道理可以算出NEXT.txt文件的存放地址。首先起首地址偏移量為62H,由此可以先計算出NEXT.txt的第一簇數據存放地址為:3C000H(根目錄地址)+20H*200H(前麵提到的用戶數據偏移量)+(62H-02H)*01H(1個簇有1個扇區)*200H=4C000H。而第一個簇地址存放在FAT1中的:1000H(FAT1起始地址)+62H*02H=10C4H。而10C4H地址上的數據為:FF FF,即結束了,也就是說由於NTXT.txt不滿一個簇,那麼隻能分配到一個簇的地址空間。


 



點擊看大圖


 


 點擊看大圖

最後更新:2017-04-03 05:40:06

  上一篇:go Akka相關概念理解
  下一篇:go 【JSP開發】IE瀏覽器發送給服務器的HTTP協議詳解