# MBR&FAT32解析 ### 前言 sector是一個儲存裝置的最小單位(如磁碟),大多為512bytes ### 整個流程 MBR (master boot record) 主開機目錄 -> MBR.partition entry1取得第一個file system(ex:fat32) 起始位址 -> 到fat32起始位址, fat32第一個sector(boot sector)可以得到fat32 file system資訊 -> 算出root directory table位址 -> 每個entry in the table有紀錄first cluster index -> fat table對每個cluster都有對應的描述 ### MBR格式 每個儲存裝置前512bytes都會是MBR(Master boot record) 再從MBR的partition table找到在這個儲存裝置下存有的各個檔案系統的起始位置 擷取部份之MBR結構: ![](https://i.imgur.com/lQrrG3c.png) 從0x1BE開始,存有一個partition entry 從0x1CE開始,存有下一個partition entry Partition entry結構如下圖: ![](https://i.imgur.com/pscwKXv.png) 在表中0x08存有Logical Block Address(LBA) of first sector, 因此也就是0x1be + 0x08 = 0x1c6 第一個檔案系統的起始位址是0x1c6 ~ 0x1c9(4 bytes) 第二個檔案系統的起始位址是0x1d6 ~ 0x1d9(4 bytes) 依此類推 ### FAT格式 而在每個檔案系統的起始位置,以fat32為例(如下圖), 一開始就是主啟動區(存放著這個檔案系統的各個資訊), 架構圖如下: ![](https://i.imgur.com/s4iwO0C.png) 在主啟動區中: | offset | representation | len | | -------- | -------- | -------- | | 0xe | 有多少sector是被預留的(包含主啟動區) | 2 bytes | | 0x10 | 有多少個file allocation table(檔案配置表) | 1 byte | | 0x24 | 每個檔案配置表佔著幾個sector | 4 bytes | | 0x2c | 根目錄的起始sector index | 4 bytes | - 其他主啟動區資訊可以reference最底下的連結 所以只要知道資料的cluster index,就可以用下面公式推出他的位址 ```c= 起始位置(檔案系統(ex:fat32)主啟動區開頭位址) + (有多少sector是被預留的 + 有多少個file allocation table * 每個檔案配置表佔著幾個sector)*sector size+ (起始cluster index-2)*sector_number_per_cluster //sector size(大多是512 bytes) ``` ### fat32檔案跟資料夾儲存方式 - 一個檔案至少用一個cluster存(cluster是fat的基本單位!) - 一個cluster一定是sector的倍數(一個sector=512bytes) 檔案配置表中用4bytes描述一個cluster,第一個32bytes描述cluster的index1的區塊 這32bytes的內容對應如下圖 ![](https://i.imgur.com/G3kegqv.png) 若這個cluster非空閒(被佔用),則會存著下一個cluster index, 這樣就可以像似link list一樣把同一個檔案下的所有內容用link list串接起來 檔案結尾用0xFFF8-0xFFFF表示 而在root directory table會紀錄中會紀錄每個檔案的起始cluster index ### ROOT DIRECTORY TABLE(SFN) ![](https://i.imgur.com/byQJGm9.png) - 一個檔案用32bytes去儲存,存有file size, 第一個cluster index, 檔案屬性等等 - 資料夾也都是用cluster裝一個這種table去做描述,只是會有兩個entry,一個指向自己,一個指向parent ### 範例 我們給定一個img file, 其中前面512 bytes是MBR區域(0-0x1ff),MBR結尾字符55aa 除此之外,我們可以藉由0x1c6-0x1c9(0x00000800 = 2048) 這四個bytes推算出2048*512 = 0x100000(1048576)這個位址->fat32檔案系統的起始位址 檔案系統的size是97952(位址是0x1ca-0x1cd)(0x00017ea0) MBR如下圖: ![](https://i.imgur.com/ECNZ83v.png) Fat32主啟動區如下圖: ![](https://i.imgur.com/W1uh0AZ.png) 再經由上面的table對應出各個參數的值, 例如: root_clstr_index is 2(根目錄的起始sector index ) count_of_reserved is 32(有多少sector是被預留的) fat_num is 2(有多少個file allocation table(檔案配置表)) sectors_num_per_fat is 754(1個file allocation table有多少sectors) 而檔案的目錄大多儲存在根目錄(也就是檔案配置表#2之後), 因此我們可以藉由換算 32+2\*754 = 1540 sectors 1540\*512 = 788480(0xc0800) 0xc0800 + 此fat32檔案系統之起始位置(0x100000) = 0x1c0800 ![](https://i.imgur.com/AtMNiTz.png) 也就可以找到我們檔案目錄了(如:bootcodebin, start.elf, kernel8.img..) 其中BOOTCODEBIN的起始cluster index = 0x0003 其中KERNEL8.IMG的起始cluster index = 0x16ae 以bootcodebin為例, 起始index = 3 對應於0x0010400c(index = 3)存著下一個index(0x00000004)被BOOTCODEBIN所擁有 file size = 0xcc50(52304) bytes 因此它會佔用52304/512個sectors = 103(0x67) 故0x69-0x03剛好就是0x67個 ![](https://i.imgur.com/bi6NGs2.png) 而這些檔案名稱怎麼存在這些目錄中,又有分Short Filenames(SFN) vs. Long Filenames(LFN) 除此之外, 也可以利用linux command去解析檔案系統或儲存裝置 ```shell= file -s ./sfn_nctuos.img ``` 其他也可以參考 https://wiki.archlinux.org/title/FAT https://zh.wikipedia.org/wiki/%E6%AA%94%E6%A1%88%E9%85%8D%E7%BD%AE%E8%A1%A8 https://en.wikipedia.org/wiki/Master_boot_record https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system https://www.cse.scu.edu/~tschwarz/coen252_07Fall/Lectures/FAT.html https://www.pjrc.com/tech/8051/ide/fat32.html ###### tags: `fat32` `mbr`