Filesystem?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Filesystem?

Post by pcmattman »

Hello all, does anyone know anywhere where I could find tutorials on reading the FAT filesystem? I've FINALLY got working floppy drivers for my OS, but I really can't do anything with them until I can read a filesystem.

The driver supports reading and writing of blocks of sectors, by the way.
m
Member
Member
Posts: 67
Joined: Sat Nov 25, 2006 6:33 am
Location: PRC

Post by m »

Recommend reading the official document.

http://www.microsoft.com/whdc/system/pl ... down.mspx?

It includes the FAT12/16/32 specification.

It's not very long and covers every aspect of the FAT family(including long name compability and supporting).

(I know the exact idea on how a FAT table works,but I found the expression with pointers in the official document confusing?)
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

The document confuses me to no end... I got out my hex editor and looked at the floppy I'm trying to work off to see if that would help, it didn't :(.

Is there anywhere that I could find code to read a FAT filesystem?
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

http://en.wikipedia.org/wiki/File_Allocation_Table

This contains quite a bit of information about FAT..

I generally try avoiding the FS since Microsoft patented VFAT and FAT32.. :?

..but I ignore patents anyway :wink:
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Well, I'm working on implementing it, so don't think I'm just trying to get out of doing some work... Thanks for the link, I'll look into it.
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

I'd strongly recommend that you try Norton's Diskedit software.
It's a disk hexeditor -- but it shows extremely clearly how FAT filesystems are put together. It's part of the Norton Utilities -- you probably already have a copy.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

As far as I know I don't have a copy... My trial of the Hex Workshop is about to expire :(... But using it I can see the FAT data.

The one question I have now is, how do I go from the cluster number to the sector number (ie. FAT12, cluster number of file is in 2 bytes, offset 26 of file entry)? If I can get that, then I'll be able to finally do all the file stuff I want to do.

Edit: the problem is, the cluster number (I've found it's the sector number, Sectors per Cluster = 1 on FAT12) is not the same as the actual location on the disk... any ideas?
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

If you're looking for a free hex editor.. why not try sourceforge?

It's likely you're using Windows so: http://hexplorer.sourceforge.net/

http://sourceforge.net/search/?type_of_ ... hex+editor

have fun.. :wink:
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Brynet-Inc wrote: I generally try avoiding the FS since Microsoft patented VFAT and FAT32.. :?

..but I ignore patents anyway :wink:
If I implement this in my OS, where do I stand as far as patents are concerned? I saw someone write before about 'clean room' disassembly being okay - which must mean that if I read about FAT32 from a 3rd party source and then implement it, I'm ok?

Not that my hobby OS is ever going to get big enough to interest M$, though... :)

Adam
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

AJ wrote:
Brynet-Inc wrote: I generally try avoiding the FS since Microsoft patented VFAT and FAT32.. :?

..but I ignore patents anyway :wink:
If I implement this in my OS, where do I stand as far as patents are concerned? I saw someone write before about 'clean room' disassembly being okay - which must mean that if I read about FAT32 from a 3rd party source and then implement it, I'm ok?

Not that my hobby OS is ever going to get big enough to interest M$, though... :)

Adam
The BSD's currently support every known "flavour" of FAT, That would be a good starting point I guess, I really don't know what it means for people trying to support VFAT/FAT32 though.. Microsoft has taken no actions as of yet. (I think..)

In all seriousness I think the only people that have to worry about this are Americans.

Then again, I know sh*t about patent laws.. 8)
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

Dex simple guild to FAT12.
First you need to load the fat in to memory and also the root dir
(as fat12 are not very big you we load them whole).We also load the boot sector, as we need
the info stored in the BPB. So let load a file from the disk. First the name of file needs
to be converted to a format the can be compared to the on stored in the root dir, which means
like this MYFILE EXE now as you can see its uppercase and packet out with space if less than
8 letters. So if you take user input for name of file to load, you will need to write some code
to convert the name as above.
Let for now say we want to find if "MYFILE EXE" is on the floppy, we would point say esi to the
Name in memory and edi to the start of the root dir in memory. The first thing we test for is edi
0, which means end of root dir and no file found, if not we can do a "repe cmpsb" (cx should = 11)
and if = we have found the file. if not = we add 32 to edi and try again.
But lets say it was = :), we than add 21 to edi and get what stored there (as this is the first
cluster number).
NOTE: when coding the "repe cmpsb" remember to pusha and popa before and after.

Now as we are talking fat12 1 cluster = 1 sector or 512bytes, Now our of all the fats, fat12 is
the biggest B**h, as it reprsents a pointer entry of 12bits or 1 1/2 bytes :(, the first 2 entrys
in the fat, for fat12 contains FOF and FFn and reprsent cluster 0 and 1, so here how it would look:
FAT ENTRYS
*************************************************************************
*F0F*FF.*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*
*************************************************************************
0 1 2 3 4 5 and so on, these are relative cluster numbers

Now lets go back to our file "MYFILE EXE", lets say that it's the only file on the floppy, the
relative cluster number would be 0002h, it would look somthing like this
FAT ENTRYS
*************************************************************************
*F0F*FF.*003*004*FFF*...*...*...*...*...*...*...*...*...*...*...*...*...*
*************************************************************************
0 1 2 3 4 5 and so on, these are relative cluster numbers

NOTE: If you looked at them in a hex editor, the bytes would be reversed.
Now to help you to see what to do next, i will show you some simple code.

Code: Select all

 ;----------------------------------------------------;
 ; Load entire a program.                             ;
 ;----------------------------------------------------;
LoadImage:
        mov   ax,[cluster]   ; In here is the cluster we saved
        mov   [FloppyTest],0 ; this is the nunmber of retrys
ReadNextClusterUP:
        call  ClusterLBA     ; convert
        call  ReadSectors    ; your read floppy function
        jc    ErrorFloppy    ; error
 ;----------------------------------------------------;
 ; compute next cluster.                              ;
 ;----------------------------------------------------;
        mov   ax,word[cluster] ; here is the cluster number (2)
        mov   cx,ax
        mov   dx,ax
        shr   dx,0x0001 ; div it by 2 = (1)
        add   cx,dx ; = (3)
        mov   esi,BpbFat12 move the address of the the FAT into esi
        add   esi,ecx ; add (3) to the address
        mov   dx,word [ds:esi] ;load whats at that address, in to DX
        test  ax,0x0001 ; test if its odd or even ?
        jnz   OddCluster
EvenCluster:
        and   dx,0000111111111111b ; if even 0 out right most nibble
        jmp   Done
OddCluster:
        shr   dx,0x0004  ; if odd shift 4 right
Done:
        mov   word [cluster],dx ; Now test if its FF0H eg end of file
        cmp   dx,0x0FF0
        jb    LoadImage ; if not load some more as its not end of file.
 ;----------------------------------------------------;
 ; ExitSucsess.                                       ;
 ;----------------------------------------------------;
ExitSucsess:
        call  Fdd_motor_off
        mov   [ErrorCode],0
        pop   ds
        pop   es
        popad
        mov   ebx,dword[FddSectorsLoadedCount] ; Put number of sectors load, in ebx.
        mov   ah,0
        clc
        ret
 ;----------------------------------------------------;
 ; ErrorFloppy.                                       ;
 ;----------------------------------------------------;
ErrorFloppy:
        call  Fdd_motor_off
        pop   ds
        pop   es
        popad
        mov   ah,byte[ErrorCode]
        stc
        ret

 ;----------------------------------------------------;
 ; ReadSectors.                                       ;
 ;----------------------------------------------------;

ReadSectors:
        pushad
        push  es
        push  ds
        call  LBAcHs
TryReadFloppyAgain:
        mov   ch,byte [absoluteTrack]
        mov   cl,byte [absoluteSector]
        mov   dh,byte [absoluteHead]
        mov   dl,byte [bsDriveNumber]
        call  FddRead ; you call your floppy function here
        jnc   FloppyReadOK

 ;----------------------------------------------------;
 ; Try Reading floppy 3 time.                         ;
 ;----------------------------------------------------;
        inc   [FloppyTest]
        cmp   [FloppyTest],4
        jae    @f
        call  FddRecalibrate
        jmp   TryReadFloppyAgain
 ;----------------------------------------------------;
 ; Move data from DMA buffer, to image address.       ;
 ;----------------------------------------------------;
FloppyReadOK:
        mov   cx,512
        mov   ax,sys_data
        mov   ds,ax
        mov   es,ax
        mov   esi,OffsetDma2Buffer ; this points to the DMAbuffer
        mov   edi,[LoadFileToAddress] ; this points to the file load address
        add   edi,[FileLoadCount]; each time we loop, we need to add 512 more bytes
        rep   movsb
        add   [FileLoadCount],512
        add   [FddSectorsLoadedCount],1  ; add 1 to number of sectors load count.
 ;----------------------------------------------------;
 ; ExitSucsess.                                       ;
 ;----------------------------------------------------;
        pop   ds
        pop   es
        popad
        clc
        ret
 ;----------------------------------------------------;
 ; Error.                                             ;
 ;----------------------------------------------------;
@@:
        pop   ds
        pop   es
        popad
        stc
        ret

 ;----------------------------------------------------;
 ; LBAcHs.                                            ;
 ;----------------------------------------------------;

LBAcHs:
        div   word [bpbSectorsPerTrack]
        inc   dl
        mov   byte [absoluteSector],dl
        xor   dx,dx
        div   word [bpbHeadsPerCylinder]
        mov   byte [absoluteHead],dl
        mov   byte [absoluteTrack],al
        ret

 ;----------------------------------------------------;
 ; ClusterLBA.                                        ;
 ;----------------------------------------------------;

ClusterLBA:
	sub   ax,2 ;we sub the first 2 entrys
	xor   cx,cx
	mov   cl,byte[bpbSectorsPerCluster] ; in this case 1
	mul   cx
	add   ax, word [DataStart] ; here is the start of the data on the floppy
	ret
; NOTE: You can get the DATA start address by Reserved_Sectors + FAT_Sectors + Root_Sectors

Now this code should be clear, but just in case, If we were using fat16 it would be much simpler
As we could go through the FAT by just adding 2bytes (eg:16bits or FAT16), But as we are using
FAT12 (or 12bits) we load 16 bits and test if even or odd, we then acording to this shift it right
4 bits or blank off 4 bits.

That's all folks ;).
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Thanks, Dex. It still doesn't solve my problem. In the entry for, say my kernel (kernel.bin) the cluster number is apparently (in the hex editor) EC00, which is 236 in decimal. The problem is, kernel.bin is actually at sector 233... Why is there 3 sectors difference? Is there some value I've forgotten to subtract or something like that?

Edit: I re-read the FAT docs, looked at the info they give about sector numbers etc... Below is all the working I've been doing (my kernel is at sector 233):

Code: Select all

KERNEL.BIN cluster = 00CE = 206 (EC = 236)
Correct? No, starts at 233
236 - 233 = 3...

RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec – 1)) / BPB_BytsPerSec;
= ( ( 224 * 32 ) + ( 512 - 1 ) ) / 512;
= ( 7168 + 511 ) / 512
= 7679 / 512 = 14.998046875 = 15 ??? decimals???

FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors;
= 1 + ( 2 * 9 ) + 14.998046875 = 33

FirstSectorofCluster = ((N – 2) * BPB_SecPerClus) + FirstDataSector;
= ( ( 236 - 2 ) * 1 ) + 33 = 267
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Post by Candy »

Code: Select all

KERNEL.BIN cluster = 00CE = 206 (EC = 236)

RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec – 1)) / BPB_BytsPerSec;
= ( ( 224 * 32 ) + ( 512 - 1 ) ) / 512;
= ( 7168 + 511 ) / 512
= 7679 / 512 = 14.998046875 => 14 (cutoff)

FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors;
= 1 + ( 2 * 9 ) + 14 = 33

FirstSectorofCluster = ((N – 2) * BPB_SecPerClus) + FirstDataSector;
= ( ( 206 - 2 ) * 1 ) + 33 = 235
How did you get the CE out of the disk? I'm doubting the validity of it...
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

I've actually finally got it! Turns out, I was reading in the hex editor the wrong file :oops: Now the only problem is how to convert two character bytes into one short...

Code: Select all

short Sector = ( buff[j+26] << 8 ) | buff[j+27];
buff is the full sector (char), j is the offset of the entry.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Got it... :D

Code: Select all

short Sector = ( ( buff[j+27] << 8 ) | buff[j+26] ) + 31;
Forgot the the bytes should be reversed...
Post Reply