#!/usr/bin/perl -w

#
# author : Frank Dietrich <bits_n_bytes@gmx.de>  20-Jan-2008
# 
# license: GPL 2
# 
# display information about FAT boot sector image
# 
# create image: dd if=/dev/sda1 of=bootsector.bin bs=512 count=1
# 
# used sources:  http://de.wikipedia.org/wiki/File_Allocation_Table#Bootsektor
#                http://support.microsoft.com/kb/q140418/
# 

use strict;
use Fcntl qw(O_RDONLY);

sub info_bootsec {
    my $buff;
    my $cnt;
    
    my $filename="bootsector.bin";

    if (!sysopen IMAGE, $filename, O_RDONLY) {
      warn "can't open image file $filename";
      return -1;
    }
                          
    $cnt = sysread IMAGE, $buff, 512;
    if ($cnt < 512) {
      warn "Image file has not the correct size (at least 512 byte).\n" . 
           "Could only read $cnt bytes.\n";
      return -1;
    }

    printf "information valid only for FAT32 boot sector\n";
    printf "--------------------------------------------\n";
    printf "OEM identifier        : %s\n", unpack 'A8', substr($buff, 3, 8);
    printf "bytes per sector      : %s\n", unpack 'v', substr($buff, 11, 2);
    printf "sectors per cluster   : %s\n", unpack 'C', substr($buff, 12, 1);
    printf "reserved sectors      : %s\n", unpack 'v', substr($buff, 13, 2);
    printf "number of FATs        : %s\n", unpack 'C', substr($buff, 16, 1);
    printf "root entries          : %s\n", unpack 'v', substr($buff, 17, 2);
    printf "number of sectors     : %s\n", unpack 'v', substr($buff, 19, 2);
    printf "media descriptor      : %s\n", uc (unpack 'H2', substr($buff, 21, 1));
    printf "sectors per FAT       : %s\n", unpack 'v', substr($buff, 22, 2);
    printf "sectors per head      : %s\n", unpack 'v', substr($buff, 24, 2);
    printf "heads per cylinder    : %s\n", unpack 'v', substr($buff, 26, 2);
    printf "hidden sectors        : %s\n", unpack 'V', substr($buff, 28, 4);
    printf "big number of sectors : %s\n", unpack 'V', substr($buff, 32, 4);
    printf "sectors per FAT       : %s\n", unpack 'V', substr($buff, 36, 4);
    printf "FAT flags             : %s\n", uc (unpack 'H4', substr($buff, 40, 2));
    printf "FAT32 version         : %s\n", uc (unpack 'H4', substr($buff, 42, 2));
    printf "root directory start  : %s\n", unpack 'V', substr($buff, 44, 4);
    printf "filesystem info sector: %s\n", unpack 'v', substr($buff, 48, 2);
    printf "backup boot sector    : %s\n", unpack 'v', substr($buff, 50, 2);
    printf "reserved              : %s\n", uc (unpack 'H24', substr($buff, 52, 12));
    printf "physical BIOS drive   : %s\n", unpack 'C', substr($buff, 64, 1);
    printf "reserved              : %s\n", uc (unpack 'H2', substr($buff, 65, 1));
    printf "signature             : %s\n", uc (unpack 'H2', substr($buff, 66, 1));
    printf "filesystem ID         : %s\n", uc (unpack 'H8', substr($buff, 67, 4));
    printf "label (unused)        : %s\n", unpack 'A11', substr($buff, 71, 11);
    printf "FAT version           : %s\n", unpack 'A8', substr($buff, 82, 8);
    printf "BIOS boot signature   : %s\n", uc (unpack 'H4', substr($buff, 510, 2));

    return 0;
}

my $rc = &info_bootsec;

exit $rc;

