Filesystem?
-
- 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?
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.
The driver supports reading and writing of blocks of sectors, by the way.
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?)
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?)
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
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
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
-
- 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:
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?
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?
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
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..
It's likely you're using Windows so: http://hexplorer.sourceforge.net/
http://sourceforge.net/search/?type_of_ ... hex+editor
have fun..
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?Brynet-Inc wrote: I generally try avoiding the FS since Microsoft patented VFAT and FAT32..
..but I ignore patents anyway
Not that my hobby OS is ever going to get big enough to interest M$, though...
Adam
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
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..)AJ wrote: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?Brynet-Inc wrote: I generally try avoiding the FS since Microsoft patented VFAT and FAT32..
..but I ignore patents anyway
Not that my hobby OS is ever going to get big enough to interest M$, though...
Adam
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..
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.
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 .
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
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 .
-
- 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:
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):
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
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
-
- 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:
I've actually finally got it! Turns out, I was reading in the hex editor the wrong file Now the only problem is how to convert two character bytes into one short...
buff is the full sector (char), j is the offset of the entry.
Code: Select all
short Sector = ( buff[j+26] << 8 ) | buff[j+27];
-
- 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:
Got it...
Forgot the the bytes should be reversed...
Code: Select all
short Sector = ( ( buff[j+27] << 8 ) | buff[j+26] ) + 31;