The Skinny on FAT



    FAT. DOS File Allocation Table that is. The FAT is
    the first sectors on a disk that tell the operating
    system where to find a file, how much of it there
    is and where all the pieces are. It also marks the
    sectors as used, full or bad so the system can
    determine where to place a file. Ok...Sounds easy.
    This information can be found all over the internet.
    But have you ever tried to figure it out? Well I
    did, and after a lot of looking and reading and
    playing with disk, this is what I've learned...
        The DOS disk is laid out in tracks, also
    called cylinders. Each track has sectors. And there
    are two sides, so 2 heads. That is where simple
    ends.
        A disk can have any number of tracks, but most
    1.44 floppies have 80. This is pretty easy but remember
    tracks are also called cylinders. Track 0 is on the
    outer edge of the disk with track 79 on the inter edge.
    All tracks have the same number of sectors even though
    the outer tracks have more room.
        A track can have any number of sectors, but most
    1.44 floppies have 18. This is set by a value in the
    Bios Parameter Block, BPB, which is in first of the
    boot sector.
        A disk can also have clusters. The value can also
    be determined from the BPB. Clusters are a group of
    sectors. On most 1.44 floppies there are 1 sector
    per cluster.
        Now...With all this, are you confused? Well, just
    hold on, it gets better.

    Absolute Sector

        Absolute sector is addressing the disk by head, track
    and sector. It is the way the controller and the BIOS
    access the disk. It is also the way to install you own
    bootstrap code or manually work on the FAT.
        So where is the FAT? Let's take a look.

        HEAD 0    TRACK 0    SECTOR 1
    This is the boot code sector. It is also where the BPB
    is located.

        Program start.
        Jump over data        ;Three bytes off start.
        NOP                   ;If short jump, must have NOP to make 3 bytes
        OEM_ID            db 8 bytes
        BytesPerSector    dw 0x0200        ;512 bytes per sector
        SectorsPerCluster db 0x01          ;1 sector per cluster
        ReservedSectors   dw 0x0001        ;Reserved sectors.. ie boot sector
        TotalFats         db 0x02          ;2 copies of the FAT
        MaxRootEntries    dw 0x0E0         ;Number of entries in the root. 224
        TotalSectors      dw 0x0B40        ;Number of sectors in volume 2880
        MediaDescriptor   db 0xF0          ; 1.44 floppy
        SectorsPerFat     dw 0x0009        ;Number of sectors in a FAT 9
        SectorsPerTrack   dw 0x0012        ;Sectors per Track 18
        NumHeads          dw 0x0002        ;2 heads
        HiddenSectors     dd 0x00000000
        TotalSectorsLarge dd 0x00000000
        DriveNumber       db 0x00
        Flags             db 0x00
        Signature        db 0x29
        VolumeID          dd 0xFFFFFFFF
        VolumeLabel       db "XXXXXXXXXXXX" ;12 bytes 8+"."+3
        SystemID          db "FAT12   "     ;8 bytes

        Code starts here.

        At byte 510 is stored the word 0xAA55. This is what the
    BIOS looks for to see if the disk is a boot disk.

        HEAD 0    TRACK 0    SECTOR 2
        This is the start of the FAT. To defy logic, instead
    of going head 0 then head 1, DOS sticks with head 0
    till sector 18. This can really confuse you at first.
        Anyway. From looking at the BPB we see that the
    FAT is 9 sectors long and there are two copies. So
    Starting here the FAT track table goes all the way
    to HEAD 0     TRACK 0     SECTOR 18

        HEAD 1    TRACK 0    SECTOR 1
        Because the boot sector took one sector, one sector
    of the second FAT wraps to head 1. So head 1, track 0 and
    sector 1 is the last sector of the FAT sector table.

        HEAD 1    TRACK 0    SECTOR 2
        This is the first sector of the FAT directory. This is
    where programs look to see what's on the disk. Each entry
    is 32 bytes long. The name of the file, date/time stamp,
    attribute, start sector and length are located here. 32 bytes
    times the number of entries, 224, gives 7168 bytes. Divide
    that by the the number of bytes per sector, 512, you get
    14 sectors. So the directory table is 14 sectors long.

        HEAD 1    TRACK 0    SECTOR 16
        This is the first sector of the data area. It is here
    that the actual files are kept.

        So. Now that we know where we are at, you might be asking
    how do you find the file. Well..Now for the really fun,
    fun stuff.

    Logical Sector Addressing

        The location of the file is marked in the FAT in logical
    sector addressing. Instead of saying the file is at head 0,
    track 0, sector 1, it is at sector 0. This does make it easier
    to store the location, but requires a couple of math formulas
    to get back to absolute sector.
        If you take a look at a directory table you can see how
    this works.

        The first 11 bytes are the file name:
    0x44 0x4F 0x4E 0x54 0x44 0x41 0x4D 0x4E 0x4D 0x4F 0x44
    Dontdamn mod    DOS adds the period.
        The next 1 byte is the attribute:
    0x20    100000 Binary which stands for Archive
        Others are:
    0x01    000001    Read only
    0x02    000010    Hidden
    0x04    000100    System file
    0x08    001000    Volume ID
    0x10    010000    Directory
        The next 8 bytes are reserved:
    0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
        The next 2 bytes are index in EA Data:
    0x00 0x00
        The next 4 bytes are the time/date stamp, encoded:
    0x5A 0xA4 0x5D 0x18
        The next 2 bytes are the entry cluster in the file chain:
    0x02 0x00
        The next 4 bytes are the file size in bytes:
    0xFF 0x20 0x04 0x00
 
        If you look at bytes 26 and 27,(remember to start counting
    from 0) 0x02 and 0x00 in this example. This is the
    starting cluster for this file. Because of the way DOS
    stores numbers, this is actually 0x00 0x02 or 2. So this
    file starts at cluster 2. More on how to find where this
    is in a minute.

        First, let's look at the sector table at head 0, track 0
    and sector 2.
 
    
      
        Take your starting number, 2 and multiply it by 1.5.
    This gives you three. Now look at the sector table and get
    the third and fourth byte. 0x03 0x40 Reverse their order to
    get 0x4003. Because our starting number, 3, was a whole number
    we AND the hexadecimal number with 0x0FFF to get 3.
        Multiply 3 by 1.5 to get 4.5. So go to the table and
    get the 4th and 5th bytes. 0x40 0x00 Reverse them 0x00 0x40
    to get 0x40. Because 4.5 was not a whole number we shift
    0x40 to the right to get 0x04. Or 4 decimal.
        Multiply 4 by 1.5 to get 6. So go to the table and
    get the 6th and 7th bytes. 0x05 0x60 Reverse them 0x60 0x05
    to get 0x6005. Because 6 is a whole number we AND 0x6005
    and 0x0FFF to get 5.
        Continue until you get the bytes 0xFF 0x0F. When they
    are reversed they form 0x0FFF which marks the end sector
    of the file.
        To find the logical sectors, take the numbers and
    subtract 2:
    3-2=1, 4-2=2, 5-2=3 and so on.
        Multiply that number by the number of bytes in a sector.
    1*0x200=0x200 2*0x200=0x400 3*0x200=600 and so on.
        Now add that number to the offset of the FAT. On this disk:
    1 reserved                           0x0200
    2 FATs at 9 sectors each. (9*2)*512  0x2400
    1 Directory 224 entries of 32 byte   0x1C00
    Total                                0x4200

        So add 0x200 to 0x4200 to get 0x4400. Now divide this by
    bytes per sector (512 or 0x200) to get logical sector 34
        0x4200 + 0x400 = 0x4600 / 0x200 = 0x23     sector 35
        0x4200 + 0x600 = 0x4800 / 0x200 = 0x24     sector 36
    and so on till the end.

        Now that we know the logical sector, you might be wondering
    how to get it to absolute sector so we can read it. Well
    we use a few formulas to figure it out.
        They are:
    sector = ( logical sector MOD sector per track) + 1
    head = (logical sector \ sector per track ) MOD number of heads
    track = logical sector \ (sector per track * number of heads)
 
    Note that this is integer division instead of floating point
    division. And also Modulo math. If you can't figure this out
    just turn on QBasic and enter a quick formula.
        So. Using the formulas above we get:
    sector= (34 MOD 512)+1=        17
    head=   (34 \ 512) MOD 2=       1
    track=   34 \ (512 *2)=         0
        Our file starts at Head 1 Track 0 Sector 17
        The next sector    Head 1 Track 0 Sector 18
        The next sector    Head 0 Track 1 Sector 1
    and so on till the end.

        There you go. The skinny on the FAT. I hope that
    this helps someone. I know I did a lot of searching
    and playing with disk to figure this out. Most places
    tell you how it works but not where it is located
    on the disk.
        A note for the OS programer. DOS does not read
    the second FAT. I have placed a 512 byte banner at the
    last sector of the second fat and called it on boot.
        I made the banner in QuickBasic and used bsave to
    save it then striped the header off and padded to 512.
    I may try loading it in a sector and marking it bad.
    (See basic still has a use. :^)
 

    If you have a comment or question, please feel free
    to send me an Email.