[coreboot] r70 - trunk/filo/fs

svn at coreboot.org svn at coreboot.org
Tue Sep 30 11:42:37 CEST 2008


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;





More information about the coreboot mailing list