Using a struct for the FAT Bios Parameter Block

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
User avatar
Stevo14
Member
Member
Posts: 179
Joined: Fri Mar 07, 2008 3:40 am
Location: Arad, Romania

Using a struct for the FAT Bios Parameter Block

Post by Stevo14 »

Upon opening and reading the official FAT manual from (the one and only) Microsoft, and seeing their nicely formatted table that explains the Bios Parameter Block, I thought it would be nice to encase it in a structure for easy access. Basically what I wanted was syntax like:

Code: Select all

fat_boot->boot_signature;
So first I read the bytes from the disk (at the start of the first partition):

Code: Select all

ata_read_bytes(drive, bs, partition_base_sector, 0, 512);
And then I allocate a new BPB and memcpy the data straight into it:

Code: Select all

fat_BS_t *fat_boot = (fat_BS_t*)kmalloc(sizeof(fat_BS_t));
memcpy(fat_boot,bs,sizeof(fat_BS_t));
However, when I try to access part of the structure, for instance the signature:

Code: Select all

write_hex(fat_boot->boot_signature);
It spews out the wrong value, and I can see no consistent pattern as to which value it spews (except that it spews the same wrong value each time).

Here is how I declare the structure:

Code: Select all

typedef struct fat_BS
{
	unsigned char 		bootjmp[3];
	unsigned char 		oem_name[8];
	unsigned short 	        bytes_per_sector;
	unsigned char		sectors_per_cluster;
	unsigned short		reserved_sector_count;
	unsigned char		table_count;
	unsigned short		root_entry_count;
	unsigned short		total_sectors_16;
	unsigned char		media_type;
	unsigned short		table_size_16;
	unsigned short		sectors_per_track;
	unsigned short		head_side_count;
	unsigned int 		hidden_sector_count;
	unsigned int 		total_sectors_32;
	
	//extended fat32 stuff
	unsigned int		 table_size_32;
	unsigned short		extended_flags;
	unsigned short		fat_version;
	unsigned int		 root_cluster;
	unsigned short		fat_info;
	unsigned short		backup_BS_sector;
	unsigned char 		reserved_0[12];
	unsigned char		drive_number;
	unsigned char 		reserved_1;
	unsigned char		boot_signature;
	unsigned int 		 volume_id;
	unsigned char		volume_label[11];
	unsigned char		fat_type_label[8];
	
}fat_BS_t;
I based this directly off of the manual, so there shouldn't be anything wrong with it. :)
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

You need to declare the struct as:

Code: Select all

 __attribute__((packed))


(put this after the closing curly brace). This will mean that the compiler does not try to pad out chars and short integers to the architecture word size.

Cheers,
Adam
User avatar
Stevo14
Member
Member
Posts: 179
Joined: Fri Mar 07, 2008 3:40 am
Location: Arad, Romania

Post by Stevo14 »

Thanks AJ. It works now! Ive seen that syntax used many other places and I have always wondered exactly why it was used.

It seems though that fixing this problem has brought up another one (side note: does anyone else find this common?). When I read the BPB, fat_boot->root_cluster reports 2 (which translates to offset of 0x8200), which is normal according to the manual, but it seems that the root directory, in the fat image that I'm using for testing, is actually located at offset 0xA6600 (I found it with a hex editor) which, should be cluster number 1331! I must be missing something because the manual says:
The first cluster of the root directory on a FAT32 volume is stored in BPB_RootClus.
and yet the only values that I can find at cluster number 2 (on the first partition) are all zeros.
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

Well, the way I figure out where the Root directory of my FAT32 partition starts is by doing this:

RootStart = ptrFat32->FatStart + (ptrFat32->FatCount*FatSectors);

Then I start reading the root directory. I honestly don't even use RootCluster, except in my Fat32 formating utility, I set it to 2 and forget about it. Possibly I'm doing something wrong, but my code reads/writes Fat32 drives partitioned with my utility or under windows, and windows chkdisk finds no errors in my parttition after formating, so until I find issue's, it's good to go I guess.
User avatar
Stevo14
Member
Member
Posts: 179
Joined: Fri Mar 07, 2008 3:40 am
Location: Arad, Romania

Post by Stevo14 »

RootStart = ptrFat32->FatStart + (ptrFat32->FatCount*FatSectors);
I actually figured that out earlier today. Thanks for the reply though! :)
I honestly don't even use RootCluster, except in my Fat32 formating utility, I set it to 2 and forget about it.
It is set to 2 on my test disk as well. There could be an outside chance that it points to the first data cluster of the root directory (as it does on my test disk), but I think that this is probably just a coincidence.
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

Well, glad you had that part, wasn't positive what you were using the RootCluster for. I wrote my Fat code over a year ago, so most of it isn't very fresh in my head :). I browsed my code, and the only place I saw RootCluster (besides the structure definition) was setting it to 2 in my format function. I am not positive what it points to, or what it's supposed to be used for, but I ignore it completely with no negative side effects. If you are having problems with something, let me know and i'll dig up my code and hopefully get you going in the right direction.
User avatar
Stevo14
Member
Member
Posts: 179
Joined: Fri Mar 07, 2008 3:40 am
Location: Arad, Romania

Post by Stevo14 »

Ready4Dis wrote:If you are having problems with something, let me know and i'll dig up my code and hopefully get you going in the right direction.
If I have any problems, I will be sure to post them here in the forums and maybe PM you if that is the appropriate thing to do.
Again, thanks for the help. :)
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

Yes, feel free to PM me if you want, or post on the forums, either or both is fine. I've got working Fat code, so I should be able to help you out if you need it.
Post Reply