FAT big endian changes
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1419 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
f6d05f501e
commit
582231ed01
|
@ -42,25 +42,27 @@ struct fat_bpb {
|
||||||
__u8 reserved_sects[2]; /* reserved sectors */
|
__u8 reserved_sects[2]; /* reserved sectors */
|
||||||
__u8 num_fats; /* number of FATs */
|
__u8 num_fats; /* number of FATs */
|
||||||
__u8 dir_entries[2]; /* root directory entries */
|
__u8 dir_entries[2]; /* root directory entries */
|
||||||
__u8 short_sectors[2]; /* number of sectors */
|
__u8 short_sectors[2];/* number of sectors */
|
||||||
__u8 media; /* media code (unused) */
|
__u8 media; /* media code (unused) */
|
||||||
__u16 fat_length; /* sectors/FAT */
|
__u8 fat_length[2]; /* sectors/FAT */
|
||||||
__u16 secs_track; /* sectors per track */
|
__u8 secs_track[2]; /* sectors per track */
|
||||||
__u16 heads; /* number of heads */
|
__u8 heads[2]; /* number of heads */
|
||||||
__u32 hidden; /* hidden sectors (unused) */
|
__u8 hidden[2]; /* hidden sectors (unused) */
|
||||||
__u32 long_sectors; /* number of sectors (if short_sectors == 0) */
|
__u8 long_sectors[2];/* number of sectors (if short_sectors == 0) */
|
||||||
|
|
||||||
/* The following fields are only used by FAT32 */
|
/* The following fields are only used by FAT32 */
|
||||||
__u32 fat32_length; /* sectors/FAT */
|
__u8 fat32_length[2];/* sectors/FAT */
|
||||||
__u16 flags; /* bit 8: fat mirroring, low 4: active fat */
|
__u8 flags[2]; /* bit 8: fat mirroring, low 4: active fat */
|
||||||
__u8 version[2]; /* major, minor filesystem version */
|
__u8 version[2]; /* major, minor filesystem version */
|
||||||
__u32 root_cluster; /* first cluster in root directory */
|
__u8 root_cluster[4];/* first cluster in root directory */
|
||||||
__u16 info_sector; /* filesystem info sector */
|
__u8 info_sector[2]; /* filesystem info sector */
|
||||||
__u16 backup_boot; /* backup boot sector */
|
__u8 backup_boot[2]; /* backup boot sector */
|
||||||
__u16 reserved2[6]; /* Unused */
|
__u8 reserved2[12]; /* Unused */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FAT_CVT_U16(bytarr) (* (__u16*)(bytarr))
|
#define FAT_CVT_U8(byte) (* (__u8*)(byte))
|
||||||
|
#define FAT_CVT_U16(bytarr) le16_to_cpu(* (__u16*)(bytarr))
|
||||||
|
#define FAT_CVT_U32(bytarr) le32_to_cpu(* (__u32*)(bytarr))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Defines how to differentiate a 12-bit and 16-bit FAT.
|
* Defines how to differentiate a 12-bit and 16-bit FAT.
|
||||||
|
@ -84,17 +86,17 @@ struct fat_bpb {
|
||||||
#define FAT_DIRENTRY_LENGTH 32
|
#define FAT_DIRENTRY_LENGTH 32
|
||||||
|
|
||||||
#define FAT_DIRENTRY_ATTRIB(entry) \
|
#define FAT_DIRENTRY_ATTRIB(entry) \
|
||||||
(*((unsigned char *) (entry+11)))
|
FAT_CVT_U8(entry+11)
|
||||||
#define FAT_DIRENTRY_VALID(entry) \
|
#define FAT_DIRENTRY_VALID(entry) \
|
||||||
( ((*((unsigned char *) entry)) != 0) \
|
( (FAT_CVT_U8(entry) != 0) \
|
||||||
&& ((*((unsigned char *) entry)) != 0xE5) \
|
&& (FAT_CVT_U8(entry) != 0xE5) \
|
||||||
&& !(FAT_DIRENTRY_ATTRIB(entry) & FAT_ATTRIB_NOT_OK_MASK) )
|
&& !(FAT_DIRENTRY_ATTRIB(entry) & FAT_ATTRIB_NOT_OK_MASK) )
|
||||||
#define FAT_DIRENTRY_FIRST_CLUSTER(entry) \
|
#define FAT_DIRENTRY_FIRST_CLUSTER(entry) \
|
||||||
((*((unsigned short *) (entry+26)))+(*((unsigned short *) (entry+20)) << 16))
|
(FAT_CVT_U16(entry+26)+(FAT_CVT_U16(entry+20) << 16))
|
||||||
#define FAT_DIRENTRY_FILELENGTH(entry) \
|
#define FAT_DIRENTRY_FILELENGTH(entry) \
|
||||||
(*((unsigned long *) (entry+28)))
|
FAT_CVT_U32(entry+28)
|
||||||
|
|
||||||
#define FAT_LONGDIR_ID(entry) \
|
#define FAT_LONGDIR_ID(entry) \
|
||||||
(*((unsigned char *) (entry)))
|
FAT_CVT_U8(entry)
|
||||||
#define FAT_LONGDIR_ALIASCHECKSUM(entry) \
|
#define FAT_LONGDIR_ALIASCHECKSUM(entry) \
|
||||||
(*((unsigned char *) (entry+13)))
|
FAT_CVT_U8(entry+13)
|
||||||
|
|
|
@ -17,8 +17,11 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <console/console.h>
|
||||||
|
#include <string.h>
|
||||||
#include <fs/fs.h>
|
#include <fs/fs.h>
|
||||||
#include <fs/fat.h>
|
#include <fs/fat.h>
|
||||||
|
#include <arch/byteorder.h>
|
||||||
|
|
||||||
struct fat_superblock
|
struct fat_superblock
|
||||||
{
|
{
|
||||||
|
@ -72,8 +75,6 @@ __ilog2(unsigned long x)
|
||||||
static __inline__ unsigned long
|
static __inline__ unsigned long
|
||||||
log2(unsigned long x)
|
log2(unsigned long x)
|
||||||
{
|
{
|
||||||
if ((x = ~x) == 0)
|
|
||||||
return 32;
|
|
||||||
return __ilog2(x & -x);
|
return __ilog2(x & -x);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -99,24 +100,36 @@ fat_mount (void)
|
||||||
if (bpb.sects_per_clust == 0)
|
if (bpb.sects_per_clust == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FAT_SUPER->sectsize_bits = log2 (FAT_CVT_U16 (bpb.bytes_per_sect));
|
FAT_SUPER->sectsize_bits = log2(FAT_CVT_U16(bpb.bytes_per_sect));
|
||||||
FAT_SUPER->clustsize_bits
|
FAT_SUPER->clustsize_bits
|
||||||
= FAT_SUPER->sectsize_bits + log2 (bpb.sects_per_clust);
|
= FAT_SUPER->sectsize_bits + log2(bpb.sects_per_clust);
|
||||||
|
|
||||||
|
printk_debug("BytsPerSec = %d\n", FAT_CVT_U16(bpb.bytes_per_sect));
|
||||||
|
printk_debug("SecPerClus = %d\n", bpb.sects_per_clust);
|
||||||
|
|
||||||
/* Fill in info about super block */
|
/* Fill in info about super block */
|
||||||
FAT_SUPER->num_sectors = FAT_CVT_U16 (bpb.short_sectors)
|
FAT_SUPER->num_sectors = FAT_CVT_U16(bpb.short_sectors)
|
||||||
? FAT_CVT_U16 (bpb.short_sectors) : bpb.long_sectors;
|
? FAT_CVT_U16(bpb.short_sectors) : FAT_CVT_U32(bpb.long_sectors);
|
||||||
|
|
||||||
|
printk_debug("TotSec16 = %d\n", FAT_CVT_U16(bpb.short_sectors));
|
||||||
|
printk_debug("TotSec32 = %d\n", FAT_CVT_U32(bpb.long_sectors));
|
||||||
|
|
||||||
/* FAT offset and length */
|
/* FAT offset and length */
|
||||||
FAT_SUPER->fat_offset = FAT_CVT_U16 (bpb.reserved_sects);
|
FAT_SUPER->fat_offset = FAT_CVT_U16(bpb.reserved_sects);
|
||||||
FAT_SUPER->fat_length =
|
FAT_SUPER->fat_length = FAT_CVT_U16(bpb.fat_length)
|
||||||
bpb.fat_length ? bpb.fat_length : bpb.fat32_length;
|
? FAT_CVT_U16(bpb.fat_length) : FAT_CVT_U32(bpb.fat32_length);
|
||||||
|
|
||||||
|
printk_debug("RsvdSecCnt = %d\n", FAT_CVT_U16(bpb.reserved_sects));
|
||||||
|
printk_debug("FATSx16 = %d\n", FAT_CVT_U16(bpb.fat_length));
|
||||||
|
printk_debug("FATSx32 = %d\n", FAT_CVT_U32(bpb.fat32_length));
|
||||||
|
|
||||||
/* Rootdir offset and length for FAT12/16 */
|
/* Rootdir offset and length for FAT12/16 */
|
||||||
FAT_SUPER->root_offset =
|
FAT_SUPER->root_offset =
|
||||||
FAT_SUPER->fat_offset + bpb.num_fats * FAT_SUPER->fat_length;
|
FAT_SUPER->fat_offset + bpb.num_fats * FAT_SUPER->fat_length;
|
||||||
FAT_SUPER->root_max = FAT_DIRENTRY_LENGTH * FAT_CVT_U16(bpb.dir_entries);
|
FAT_SUPER->root_max = FAT_DIRENTRY_LENGTH * FAT_CVT_U16(bpb.dir_entries);
|
||||||
|
|
||||||
|
printk_debug("RootEntCnt = %d\n", FAT_CVT_U16(bpb.dir_entries));
|
||||||
|
|
||||||
/* Data offset and number of clusters */
|
/* Data offset and number of clusters */
|
||||||
FAT_SUPER->data_offset =
|
FAT_SUPER->data_offset =
|
||||||
FAT_SUPER->root_offset
|
FAT_SUPER->root_offset
|
||||||
|
@ -132,17 +145,20 @@ fat_mount (void)
|
||||||
if (FAT_CVT_U16(bpb.dir_entries))
|
if (FAT_CVT_U16(bpb.dir_entries))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (bpb.flags & 0x0080)
|
printk_debug("We seem to be FAT32\n");
|
||||||
|
printk_debug("ExtFlags = 0x%x\n", FAT_CVT_U16(bpb.flags));
|
||||||
|
printk_debug("RootClus = %d\n", FAT_CVT_U32(bpb.root_cluster));
|
||||||
|
if (FAT_CVT_U16(bpb.flags) & 0x0080)
|
||||||
{
|
{
|
||||||
/* FAT mirroring is disabled, get active FAT */
|
/* FAT mirroring is disabled, get active FAT */
|
||||||
int active_fat = bpb.flags & 0x000f;
|
int active_fat = FAT_CVT_U16(bpb.flags) & 0x000f;
|
||||||
if (active_fat >= bpb.num_fats)
|
if (active_fat >= bpb.num_fats)
|
||||||
return 0;
|
return 0;
|
||||||
FAT_SUPER->fat_offset += active_fat * FAT_SUPER->fat_length;
|
FAT_SUPER->fat_offset += active_fat * FAT_SUPER->fat_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
FAT_SUPER->fat_size = 8;
|
FAT_SUPER->fat_size = 8;
|
||||||
FAT_SUPER->root_cluster = bpb.root_cluster;
|
FAT_SUPER->root_cluster = FAT_CVT_U32(bpb.root_cluster);
|
||||||
|
|
||||||
/* Yes the following is correct. FAT32 should be called FAT28 :) */
|
/* Yes the following is correct. FAT32 should be called FAT28 :) */
|
||||||
FAT_SUPER->clust_eof_marker = 0xffffff8;
|
FAT_SUPER->clust_eof_marker = 0xffffff8;
|
||||||
|
@ -152,6 +168,7 @@ fat_mount (void)
|
||||||
if (!FAT_SUPER->root_max)
|
if (!FAT_SUPER->root_max)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
printk_debug("We seem to be FAT12/16\n");
|
||||||
FAT_SUPER->root_cluster = -1;
|
FAT_SUPER->root_cluster = -1;
|
||||||
if (FAT_SUPER->num_clust > FAT_MAX_12BIT_CLUST)
|
if (FAT_SUPER->num_clust > FAT_MAX_12BIT_CLUST)
|
||||||
{
|
{
|
||||||
|
@ -165,7 +182,6 @@ fat_mount (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Now do some sanity checks */
|
/* Now do some sanity checks */
|
||||||
|
|
||||||
if (FAT_CVT_U16(bpb.bytes_per_sect) != (1 << FAT_SUPER->sectsize_bits)
|
if (FAT_CVT_U16(bpb.bytes_per_sect) != (1 << FAT_SUPER->sectsize_bits)
|
||||||
|
@ -183,19 +199,21 @@ fat_mount (void)
|
||||||
sizeof(first_fat), (char *)&first_fat))
|
sizeof(first_fat), (char *)&first_fat))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
printk_debug("Media = 0x%x\n", bpb.media);
|
||||||
|
|
||||||
if (FAT_SUPER->fat_size == 8)
|
if (FAT_SUPER->fat_size == 8)
|
||||||
{
|
{
|
||||||
first_fat &= 0x0fffffff;
|
first_fat = le32_to_cpu(first_fat) & 0x0fffffff;
|
||||||
magic = 0x0fffff00;
|
magic = 0x0fffff00;
|
||||||
}
|
}
|
||||||
else if (FAT_SUPER->fat_size == 4)
|
else if (FAT_SUPER->fat_size == 4)
|
||||||
{
|
{
|
||||||
first_fat &= 0x0000ffff;
|
first_fat = le32_to_cpu(first_fat) & 0x0000ffff;
|
||||||
magic = 0xff00;
|
magic = 0xff00;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
first_fat &= 0x00000fff;
|
first_fat = le32_to_cpu(first_fat) & 0x00000fff;
|
||||||
magic = 0x0f00;
|
magic = 0x0f00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,7 +273,7 @@ fat_read (char *buf, int len)
|
||||||
if (!devread (sector, 0, FAT_CACHE_SIZE, (char*) FAT_BUF))
|
if (!devread (sector, 0, FAT_CACHE_SIZE, (char*) FAT_BUF))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
next_cluster = * (unsigned long *) (FAT_BUF + (cached_pos >> 1));
|
next_cluster = FAT_CVT_U32(FAT_BUF + (cached_pos >> 1));
|
||||||
if (FAT_SUPER->fat_size == 3)
|
if (FAT_SUPER->fat_size == 3)
|
||||||
{
|
{
|
||||||
if (cached_pos & 1)
|
if (cached_pos & 1)
|
||||||
|
@ -288,7 +306,7 @@ fat_read (char *buf, int len)
|
||||||
|
|
||||||
devread(sector, offset, size, buf);
|
devread(sector, offset, size, buf);
|
||||||
|
|
||||||
disk_read_func = NULL;
|
disk_read_func = 0;
|
||||||
|
|
||||||
len -= size;
|
len -= size;
|
||||||
buf += size;
|
buf += size;
|
||||||
|
|
Loading…
Reference in New Issue