## ## References from Microsoft FAT32 File System Specification ## ## ## Copy the boot sector ## which includes the BPB (BIOS Paramter Block) ## brock@pinky-pie:~$ dd if=boot.img of=boot.boot-sector.img bs=512 count=1 1+0 records in 1+0 records out 512 bytes (512 B) copied, 0.00834778 s, 61.3 kB/s ## ## Get some BPB variables [Pages 9-12] ## ## brock@pinky-pie:~$ od -A d -j 11 -N 2 -t d2 boot.boot-sector.img 0000011 512 0000013 brock@pinky-pie:~$ BPB_BytsPerSec=512 brock@pinky-pie:~$ od -A d -j 13 -N 1 -t d1 boot.boot-sector.img 0000013 16 0000014 brock@pinky-pie:~$ BPB_SecPerClus=16 brock@pinky-pie:~$ od -A d -j 14 -N 2 -t d2 boot.boot-sector.img 0000014 16 0000016 brock@pinky-pie:~ $BPB_RsvdSecCnt=16 brock@pinky-pie:~$ od -A d -j 16 -N 1 -t d1 boot.boot-sector.img 0000016 2 0000017 brock@pinky-pie:~$ BPB_NumFATs=2 brock@pinky-pie:~$ od -A d -j 17 -N 2 -t d2 boot.boot-sector.img 0000017 512 0000019 brock@pinky-pie:~$ BPB_RootEntCnt=512 brock@pinky-pie:~$ od -A d -j 19 -N 2 -t d2 boot.boot-sector.img 0000019 0 0000021 brock@pinky-pie:~$ BPB_TotSec16=0 ## ## Because BPB_TotSec16 is 0, must check BPB_TocSec32 ## 32 bit field is needed because number of sectors exceeds 65535 ## brock@pinky-pie:~$ od -A d -j 32 -N 4 -t d4 boot.boot-sector.img 0000032 114688 0000036 brock@pinky-pie:~$ BPB_TotSec32=114688 brock@pinky-pie:~$ TotSec=$BPB_TotSec32 brock@pinky-pie:~$ echo $TotSec 114688 ## ## Sanity check: Size predicted by BPB matches /boot image ## brock@pinky-pie:~$ echo $(( $TotSec * $BPB_BytsPerSec )) 58720256 brock@pinky-pie:~$ ls -l boot.img -rw-r--r-- 1 root root 58720256 Mar 24 09:17 boot.img ## ## Following FAT Data Structure section [pp 13-14] ## ## ## Determine count of sectors in root directory (for FAT16) ## brock@pinky-pie:~$ RootDirSectors=$(( ( ( $BPB_RootEntCnt * 32 ) + ( $BPB_BytsPerSec - 1 ) ) / $BPB_BytsPerSec )) brock@pinky-pie:~$ echo $RootDirSectors 32 ## ## Another sanity check ## brock@pinky-pie:~$ echo $(( $RootDirSectors * 32 )) 1024 brock@pinky-pie:~$ echo $(( $RootDirSectors * $BPB_BytsPerSec )) 16384 brock@pinky-pie:~$ echo $(( $BPB_RootEntCnt * 32 )) 16384 ## ## Determine size of FAT ## brock@pinky-pie:~$ od -A d -j 22 -N 2 -t d2 boot.boot-sector.img 0000022 32 0000024 brock@pinky-pie:~$ BPB_FATSz16=32 brock@pinky-pie:~$ FATSz=$BPB_FATSz16 ## ## Find sector address of first data cluster ## brock@pinky-pie:~$ FirstDataSector=$(( $BPB_RsvdSecCnt + ( $BPB_NumFATs * $FATSz ) + $RootDirSectors )) brock@pinky-pie:~$ echo $FirstDataSector 112 ## ## Find number of data sectors ## brock@pinky-pie:~$ DataSec=$(( $TotSec - ( $BPB_RsvdSecCnt + ( $BPB_NumFATs * $FATSz ) + $RootDirSectors ) )) ## ## More sanity checks ## brock@pinky-pie:~$ echo $DataSec 114576 brock@pinky-pie:~$ echo $FirstDataSector 112 brock@pinky-pie:~$ echo $TotSec 114688 brock@pinky-pie:~$ echo $(( $TotSec * $BPB_BytsPerSec )) 58720256 brock@pinky-pie:~$ brock@pinky-pie:~$ ls -l boot.img -rw-r--r-- 1 root root 58720256 Mar 24 09:17 boot.img ## ## Official MS-sanctioned way to determine FAT type, FAT12, FAT16 or FAT32 ## brock@pinky-pie:~$ CountofClusters=$(( $DataSec / $BPB_SecPerClus )) brock@pinky-pie:~$ echo $CountofClusters 7161 ## ## Count is more than 2^12 and less than or equal to 2^16 ## This is a FAT16 file system ## ## Copy the root directory ## brock@pinky-pie:~$ echo $(( $BPB_RsvdSecCnt + $BPB_NumFATs * $FATSz )) 80 brock@pinky-pie:~$ echo $RootDirSectors 32 brock@pinky-pie:~$ dd if=boot.img of=boot.rootdir.img bs=512 count=32 skip=80 32+0 records in 32+0 records out 16384 bytes (16 kB) copied, 0.00549986 s, 3.0 MB/s ## ## Looking at FAT Directory structure [pp 22-...] ## ## Sanity check of first directory entry ## Looks OK ## brock@pinky-pie:~$ od -A d -j 0 -N 32 -t a boot.rootdir.img 0000000 b o o t sp sp sp sp sp sp sp bs nul nul U & 0000016 ' D ' D nul nul U & ' D nul nul nul nul nul nul 0000032 ## ## The dreaded long directory entry for bootcode.bin ## brock@pinky-pie:~$ od -A d -j 32 -N 32 -t a boot.rootdir.img 0000032 A b nul o nul o nul t nul c nul si nul enq o nul 0000048 d nul e nul . nul b nul i nul nul nul n nul nul nul 0000064 ## ## Old-style directory entry for BOOTCODE.BIN ## brock@pinky-pie:~$ od -A d -j 64 -N 32 -t a boot.rootdir.img 0000064 B O O T C O D E B I N sp nul d T % 0000080 9 E 9 E nul nul T % 9 E etx nul 0 E nul nul 0000096 ## ## Determine file size from directory entry ## brock@pinky-pie:~$ od -A d -j $(( 64 + 28 )) -N 4 -t d4 boot.rootdir.img 0000092 17840 0000096 ## ## Sanity check ## brock@pinky-pie:~$ ls -l /boot/bootcode.bin -rwxr-xr-x 1 root root 17840 Sep 25 2014 /boot/bootcode.bin ## ## Determine first cluster address for BOOTCODE.BIN ## Looks like it's 3 ## brock@pinky-pie:~$ od -A d -j $(( 64 + 26 )) -N 2 -t d2 boot.rootdir.img 0000090 3 0000092 brock@pinky-pie:~$ BOOTCODEBINCLUSTER=3 ## ## Copy the entire FAT ## brock@pinky-pie:~$ dd if=boot.img of=boot.fat.img bs=512 skip=16 count=32 32+0 records in 32+0 records out 16384 bytes (16 kB) copied, 0.0144706 s, 1.1 MB/s ## ## Look at the FAT's linked list structure ## Our file seems to be in clusters 3, 4, t ## brock@pinky-pie:~$ od -A d -j 0 -N 32 -t d2 boot.fat.img 0000000 -8 -1 0 4 5 -1 -1 -1 0000016 -1 10 -1 12 13 14 15 16 0000032 ## ## Sanity check: Cf file length and number of clusters ## brock@pinky-pie:~$ echo $*(( $BPB_SecPerClus * $BPB_BytsPerSec )) (( 16 * 512 )) brock@pinky-pie:~$ echo $(( $BPB_SecPerClus * $BPB_BytsPerSec )) 8192 brock@pinky-pie:~$ echo $(( ( 17840 - 1) / 8192 + 1 )) 3 ## ## Another look at our clusters ## brock@pinky-pie:~$ od -A d -j 6 -N 6 -t d2 boot.fat.img 0000006 4 5 -1 0000012 ## ## Get sector address of clusters ## brock@pinky-pie:~$ FirstSectorofCluster3=$((( ( 3 - 2 ) * $BPB_SecPerClus ) + $FirstDataSector )) brock@pinky-pie:~$ FirstSectorofCluster4=$((( ( 4 - 2 ) * $BPB_SecPerClus ) + $FirstDataSector )) brock@pinky-pie:~$ FirstSectorofCluster5=$((( ( 5 - 2 ) * $BPB_SecPerClus ) + $FirstDataSector )) brock@pinky-pie:~$ echo $FirstSectorofCluster3 128 brock@pinky-pie:~$ echo $FirstSectorofCluster4 144 brock@pinky-pie:~$ echo $FirstSectorofCluster5 160 ## ## Read the three clusters ## brock@pinky-pie:~$ dd if=boot.img of=boot.cluster3.img bs=512 skip=128 count=16 16+0 records in 16+0 records out 8192 bytes (8.2 kB) copied, 0.00104097 s, 7.9 MB/s brock@pinky-pie:~$ dd if=boot.img of=boot.cluster4.img bs=512 skip=144 count=16 16+0 records in 16+0 records out 8192 bytes (8.2 kB) copied, 0.00104697 s, 7.8 MB/s brock@pinky-pie:~$ dd if=boot.img of=boot.cluster5.img bs=512 skip=160 count=16 16+0 records in 16+0 records out 8192 bytes (8.2 kB) copied, 0.00118497 s, 6.9 MB/s ## ## Concatentate the three clusters and truncate to 17840 bytes ## brock@pinky-pie:~$ cat boot.cluster3.img boot.cluster4.img boot.cluster5.img > boot.clusters3-5.img brock@pinky-pie:~$ ls -l boot.cluster* -rw-r--r-- 1 brock brock 8192 Apr 7 00:02 boot.cluster3.img -rw-r--r-- 1 brock brock 8192 Apr 7 00:02 boot.cluster4.img -rw-r--r-- 1 brock brock 8192 Apr 7 00:02 boot.cluster5.img -rw-r--r-- 1 brock brock 24576 Apr 7 00:03 boot.clusters3-5.img brock@pinky-pie:~$ dd if=boot.clusters3-5.img of=boot.bootcode.bin.img bs=17840 count=1 1+0 records in 1+0 records out 17840 bytes (18 kB) copied, 0.0110697 s, 1.6 MB/s ## ## We did it! ## brock@pinky-pie:~$ ls -l boot.bootcode.bin.img -rw-r--r-- 1 brock brock 17840 Apr 7 00:04 boot.bootcode.bin.img brock@pinky-pie:~$ ls -l /boot/bootcode.bin -rwxr-xr-x 1 root root 17840 Sep 25 2014 /boot/bootcode.bin brock@pinky-pie:~$ cmp boot.bootcode.bin.img /boot/bootcode.bin brock@pinky-pie:~$ echo $? 0