Author: oxygene Date: 2008-09-30 11:42:37 +0200 (Tue, 30 Sep 2008) New Revision: 70
Modified: trunk/filo/fs/fat.h trunk/filo/fs/fsys_fat.c Log: take a closer look at the filesystem before interpreting it as FAT.
fixes #1
Modified: trunk/filo/fs/fat.h =================================================================== --- trunk/filo/fs/fat.h 2008-09-29 17:47:50 UTC (rev 69) +++ trunk/filo/fs/fat.h 2008-09-30 09:42:37 UTC (rev 70) @@ -1,6 +1,7 @@ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2001 Free Software Foundation, Inc. + * Copyright (C) 2008 coresystems GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,6 +31,35 @@ typedef __signed__ int __s32; typedef unsigned int __u32;
+ +struct fat16_extended_bpb { + __u8 drive_number; /* Physical Drive Number */ + __u8 reserved; /* "current head" */ + __u8 boot_signature; /* Extended Boot Signature 0x28 or 0x29 */ + __u8 id[4]; /* ID (serial number) */ + __u8 volumelabel[11];/* volume label */ + __s8 type[8]; /* Padded with blanks: "FAT12", "FAT16" */ +} __attribute__((packed)); + +struct fat32_extended_bpb { + /* The following fields are only used by FAT32 */ + __u32 fat32_length; /* sectors/FAT */ + __u16 flags; /* bit 8: fat mirroring, low 4: active fat */ + __u8 version[2]; /* major, minor filesystem version */ + __u32 root_cluster; /* first cluster in root directory */ + __u16 info_sector; /* filesystem info sector */ + __u16 backup_boot; /* backup boot sector */ + __u16 reserved2[12]; /* Reserved */ + /* from here on it looks like the fat12/fat16 code */ + __u8 drive_number; /* Physical Drive Number */ + __u8 reserved; /* "current head" */ + __u8 boot_signature; /* Extended Boot Signature 0x28 or 0x29 */ + __u8 id[4]; /* ID (serial number) */ + __u8 volumelabel[11];/* volume label */ + __s8 type[8]; /* Padded with blanks: "FAT32" */ +} __attribute__((packed)); + + /* Note that some shorts are not aligned, and must therefore * be declared as array of two bytes. */ @@ -50,14 +80,10 @@ __u32 hidden; /* hidden sectors (unused) */ __u32 long_sectors; /* number of sectors (if short_sectors == 0) */
- /* The following fields are only used by FAT32 */ - __u32 fat32_length; /* sectors/FAT */ - __u16 flags; /* bit 8: fat mirroring, low 4: active fat */ - __u8 version[2]; /* major, minor filesystem version */ - __u32 root_cluster; /* first cluster in root directory */ - __u16 info_sector; /* filesystem info sector */ - __u16 backup_boot; /* backup boot sector */ - __u16 reserved2[6]; /* Unused */ + union { + struct fat16_extended_bpb fat16; + struct fat32_extended_bpb fat32; + } extended; };
#define FAT_CVT_U16(bytarr) (* (__u16*)(bytarr))
Modified: trunk/filo/fs/fsys_fat.c =================================================================== --- trunk/filo/fs/fsys_fat.c 2008-09-29 17:47:50 UTC (rev 69) +++ trunk/filo/fs/fsys_fat.c 2008-09-30 09:42:37 UTC (rev 70) @@ -83,7 +83,7 @@ /* FAT offset and length */ FAT_SUPER->fat_offset = FAT_CVT_U16 (bpb.reserved_sects); FAT_SUPER->fat_length = - bpb.fat_length ? bpb.fat_length : bpb.fat32_length; + bpb.fat_length ? bpb.fat_length : bpb.extended.fat32.fat32_length;
/* Rootdir offset and length for FAT12/16 */ FAT_SUPER->root_offset = @@ -99,23 +99,31 @@ / bpb.sects_per_clust); FAT_SUPER->sects_per_clust = bpb.sects_per_clust;
+ if (strncmp(bpb.extended.fat16.type, "FAT12", 5) && + strncmp(bpb.extended.fat16.type, "FAT16", 5) && + strncmp(bpb.extended.fat32.type, "FAT32", 5)) + { + /* None of them matched. Bail out */ + return 0; + } + if (!bpb.fat_length) { /* This is a FAT32 */ if (FAT_CVT_U16(bpb.dir_entries)) return 0;
- if (bpb.flags & 0x0080) + if (bpb.extended.fat32.flags & 0x0080) { /* FAT mirroring is disabled, get active FAT */ - int active_fat = bpb.flags & 0x000f; + int active_fat = bpb.extended.fat32.flags & 0x000f; if (active_fat >= bpb.num_fats) return 0; FAT_SUPER->fat_offset += active_fat * FAT_SUPER->fat_length; }
FAT_SUPER->fat_size = 8; - FAT_SUPER->root_cluster = bpb.root_cluster; + FAT_SUPER->root_cluster = bpb.extended.fat32.root_cluster;
/* Yes the following is correct. FAT32 should be called FAT28 :) */ FAT_SUPER->clust_eof_marker = 0xffffff8;