Greetings,
I have a quick question regarding the root directory of a FAT file system (specifically, FAT12).
I'm writing myself a bootloader from scratch, it's not really gotten far beyond booting, as I realised that I'm very soon going to require a file system if I want to do much. With this in mind, I started to implement a FAT12 fs for my boot floppy.
Right now I've got the boot sector coded so that it reads a FAT off the disk into memory (I cheated a little for testing and used a windows-formatted floppy image and overwrote the first sector with my own). this works, but now i want to read the root directory. My question is, given that this is a floppy I'm using here, and there's 14 sectors allocated to the root directory, should a properly designed FAT12 fs try to keep all directory entries at the top of the root directory space? At the moment there's only one example text file on the image in question, and I'm wondering how I check for the last directory entry while reading the contents, and what should happen were i to add 2 more files, and then delete the second, does this result in a fragmentation, or should the rest of the directory entries be moved down one whenever this happens?
Reading a FAT root directory
Re: Reading a FAT root directory
Hi,
For example:
Each line is a root directory entry that points to a file in the FAT.
The first line points to a file that hasn't been deleted.
The second line points to a file that hasn't been deleted.
The third line points to a file that has been deleted.
The forth line points to a file that hasn't been deleted.
The fifth line points to a file that has been deleted.
The Sixth line is a root directory entry that is not being used, and therefore there are no more files on the disk.
When your driver gets to the third file, it should see the 0xE5 byte and skip that root directory, and go on and print the forth file. It should then skip the fifth file because of the 0xE5, and then finally go on to sixth root directory entry and find the 0x00 byte, indicating no more files and should then finish. Any new file that is written should overwrite the third root directory entry, since that file is deleted.
The pseudocode for your driver when listing the files on the disk should be:
1.Set up a counter of 224 for the number of root directory entries.
2.Increment the counter and continue if the counter does not equal 224, otherwise go to step 9.
3.Read the first byte of the root directory entry.
4.Compare it to either 0x00 or 0xE5.
5.If the first byte is 0x00, go to step 9.
6.If the first byte is 0xE5, go to step 8.
7.If the first byte is neither 0x00 or 0xE5, then the file is good so you can do whatever you want.
8.Point your driver to the next root directory entry and go back to step 2.
9.Once your driver has found a 0x00 or the counter has reached 224, then there are no more files on the disk.
Of course, the above will not work for LFN, it is only what I used for my simple "dir" command.
Hope I helped.
-U238
Yes, a properly designed FAT12 file system driver should keep all directory entries at the top of the root directory space. If a file is deleted, it's root directory entry should be replaced with the next file that is written to the disk, instead of creating a new directory entry for the new file.duran wrote:My question is, given that this is a floppy I'm using here, and there's 14 sectors allocated to the root directory, should a properly designed FAT12 fs try to keep all directory entries at the top of the root directory space?
Your driver should check for a 0x0 (0h) byte as the first byte in each root directory entry, this signifies that the directory entry is not being used, and therefore is the last file on the disk.duran wrote: At the moment there's only one example text file on the image in question, and I'm wondering how I check for the last directory entry while reading the contents
When a file on a fat12 file system is deleted, a 0xE5 (E5h) byte is set as the first byte in the root directory entry, nothing else. So your driver should just skip any entry that has the 0xE5 byte when reading or listing files.duran wrote:what should happen were i to add 2 more files, and then delete the second, does this result in a fragmentation, or should the rest of the directory entries be moved down one whenever this happens?
For example:
Code: Select all
4B 45 52 4E 45 4C 20 20 53 59 53 20 18 18 A9 23 54 3E 54 3E 00 00 56 8E 54 3E 02 00 32 01 00 00
53 4B 55 5A 20 20 20 20 54 58 54 20 18 18 AC 23 54 3E 54 3E 00 00 DA AB 46 3E 03 00 1C 00 00 00
E5 45 45 44 20 20 20 20 54 58 54 20 18 B4 12 8D 54 3E 54 3E 00 00 FC 8C 54 3E 00 00 00 00 00 00
4D 4F 50 20 20 20 20 20 54 58 54 20 18 A4 15 8D 54 3E 54 3E 00 00 05 8D 54 3E 00 00 00 00 00 00
E5 41 4A 41 52 20 20 20 54 58 54 20 18 1F 1A 8D 54 3E 54 3E 00 00 09 8D 54 3E 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
The first line points to a file that hasn't been deleted.
The second line points to a file that hasn't been deleted.
The third line points to a file that has been deleted.
The forth line points to a file that hasn't been deleted.
The fifth line points to a file that has been deleted.
The Sixth line is a root directory entry that is not being used, and therefore there are no more files on the disk.
When your driver gets to the third file, it should see the 0xE5 byte and skip that root directory, and go on and print the forth file. It should then skip the fifth file because of the 0xE5, and then finally go on to sixth root directory entry and find the 0x00 byte, indicating no more files and should then finish. Any new file that is written should overwrite the third root directory entry, since that file is deleted.
The pseudocode for your driver when listing the files on the disk should be:
1.Set up a counter of 224 for the number of root directory entries.
2.Increment the counter and continue if the counter does not equal 224, otherwise go to step 9.
3.Read the first byte of the root directory entry.
4.Compare it to either 0x00 or 0xE5.
5.If the first byte is 0x00, go to step 9.
6.If the first byte is 0xE5, go to step 8.
7.If the first byte is neither 0x00 or 0xE5, then the file is good so you can do whatever you want.
8.Point your driver to the next root directory entry and go back to step 2.
9.Once your driver has found a 0x00 or the counter has reached 224, then there are no more files on the disk.
Of course, the above will not work for LFN, it is only what I used for my simple "dir" command.
Hope I helped.
-U238
Re: Reading a FAT root directory
Disassemble a FAT12 boot sector. Here's one that's well commented:
http://www.omninerd.com/articles/PC_Boo ... ial_in_ASM
http://www.omninerd.com/articles/PC_Boo ... ial_in_ASM
Re: Reading a FAT root directory
turdus wrote:Disassemble a FAT12 boot sector. Here's one that's well commented:
http://www.omninerd.com/articles/PC_Boo ... ial_in_ASM
Forgive me if I'm wrong, but I wanted to check this:
Code: Select all
LBACHS:
xor dx, dx ; prepare dx:ax for operation
div WORD [SectorsPerTrack] ; calculate
inc dl ; adjust for sector 0
mov BYTE [absoluteSector], dl
xor dx, dx ; prepare dx:ax for operation
div WORD [NumHeads] ; calculate
mov BYTE [absoluteHead], dl
mov BYTE [absoluteTrack], al
ret
Re: Reading a FAT root directory
I cannot garantee that the above code is perfect. I've just googled it, and it was the first result. That's why I suggested to disassemble a code that you saw working and compare.duran wrote: The calculation of the cylinder value there appears to work out to something like ( LBASector / SectorsPerTrack ) / NumHeads. I thought the algorithm for computing cylinder values from LBA addresses was LBASector / ( NumHeads * SectorsPerTrack ) ?
(I've never implemented FAT12, that's too obsolete for me, I use FAT32 for EFI support. And yes, I did it the hard way, I saved a boot sector of an MSDOS partition and disassembled it, understand it, and wrote my own implementation. I've tested it with linux "mkfs.vfat -F 32" and it worked, then I forget the whole thing.)
Re: Reading a FAT root directory
Took the suck it and see approach...kinda
the code looked incorrect, so i changed it to use the canonical CHS algorithm. Everything went better than expected
FAT reads out,root directory read out. I've gotten as far as dumping the listing of the root directory to the terminal so far.
next stop, loading a kernel image, as the boot sector is getting kinda crowded now.
the code looked incorrect, so i changed it to use the canonical CHS algorithm. Everything went better than expected
FAT reads out,root directory read out. I've gotten as far as dumping the listing of the root directory to the terminal so far.
next stop, loading a kernel image, as the boot sector is getting kinda crowded now.
Re: Reading a FAT root directory
Well done! I'm glad it was useful despite of wrong LBSCHS!