diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-11-15 16:44:45 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-11-15 16:44:45 +0000 |
commit | 4bf2eeec797de1c158143d33c572ef38e6ccc015 (patch) | |
tree | 7984e3dd5ddc7d8d474bbbc53f5031863834d50f /nuttx/fs/fat | |
parent | c5c3f5ad84cce90b89cff4d88334789c2bc2e2f9 (diff) | |
download | px4-nuttx-4bf2eeec797de1c158143d33c572ef38e6ccc015.tar.gz px4-nuttx-4bf2eeec797de1c158143d33c572ef38e6ccc015.tar.bz2 px4-nuttx-4bf2eeec797de1c158143d33c572ef38e6ccc015.zip |
Add support for more FAT partitions; support for SD cards greater than 4Gb; TSC2007 touchscreen driver improvements
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4092 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/fs/fat')
-rw-r--r-- | nuttx/fs/fat/fs_fat32.h | 44 | ||||
-rw-r--r-- | nuttx/fs/fat/fs_fat32util.c | 95 |
2 files changed, 112 insertions, 27 deletions
diff --git a/nuttx/fs/fat/fs_fat32.h b/nuttx/fs/fat/fs_fat32.h index 026d87a6d..536e8fd7e 100644 --- a/nuttx/fs/fat/fs_fat32.h +++ b/nuttx/fs/fat/fs_fat32.h @@ -129,10 +129,12 @@ */ /* 446@0: Generally unused and zero; but may * include IDM Boot Manager menu entry at 8@394 */ +#define PART_ENTRY(n) (446+((n) << 4)) /* n = 0,1,2,3 */ #define PART_ENTRY1 446 /* 16@446: Partition table, first entry */ #define PART_ENTRY2 462 /* 16@462: Partition table, second entry */ - /* 32@478: Unused, should be zero */ -#define PART_SIGNATURE /* 2@510: Valid partitions have 0x55aa here */ +#define PART_ENTRY3 478 /* 16@478: Partition table, third entry */ +#define PART_ENTRY4 494 /* 16@494: Partition table, fourth entry */ +#define PART_SIGNATURE 510 /* 2@510: Valid partitions have 0x55aa here */ /**************************************************************************** * These offsets describes one partition table entry. NOTE that ent entries @@ -148,6 +150,26 @@ #define PART_SIZE 12 /* 4@12: Partition size (in sectors) */ /**************************************************************************** + * Partition table types. + */ + +#define PART_TYPE_NONE 0 /* No partition */ +#define PART_TYPE_FAT12 1 /* FAT12 */ +#define PART_TYPE_FAT16A 4 /* FAT16 (Partition smaller than 32MB) */ +#define PART_TYPE_EXT 5 /* Extended MS-DOS Partition */ +#define PART_TYPE_FAT16B 6 /* FAT16 (Partition larger than 32MB) */ +#define PART_TYPE_FAT32 11 /* FAT32 (Partition up to 2048Gb) */ +#define PART_TYPE_FAT32X 12 /* Same as 11, but uses LBA1 0x13 extensions */ +#define PART_TYPE_FAT16X 14 /* Same as 6, but uses LBA1 0x13 extensions */ +#define PART_TYPE_EXTX 15 /* Same as 5, but uses LBA1 0x13 extensions */ + +/**************************************************************************** + * Each FAT "short" 8.3 file name directory entry is 32-bytes long. + * + * Sizes and limits + */ + +/**************************************************************************** * Each FAT "short" 8.3 file name directory entry is 32-bytes long. * * Sizes and limits @@ -329,8 +351,11 @@ #define MBR_GETBOOTSIG16(p) UBYTE_VAL(p,BS16_BOOTSIG) #define MBR_GETBOOTSIG32(p) UBYTE_VAL(p,BS32_BOOTSIG) +#define PART_GETTYPE(n,p) UBYTE_VAL(p,PART_ENTRY(n)+PART_TYPE) #define PART1_GETTYPE(p) UBYTE_VAL(p,PART_ENTRY1+PART_TYPE) #define PART2_GETTYPE(p) UBYTE_VAL(p,PART_ENTRY2+PART_TYPE) +#define PART3_GETTYPE(p) UBYTE_VAL(p,PART_ENTRY3+PART_TYPE) +#define PART4_GETTYPE(p) UBYTE_VAL(p,PART_ENTRY4+PART_TYPE) #define DIR_GETATTRIBUTES(p) UBYTE_VAL(p,DIR_ATTRIBUTES) #define DIR_GETNTRES(p) UBYTE_VAL(p,DIR_NTRES) @@ -351,8 +376,11 @@ #define MBR_PUTBOOTSIG16(p,v) UBYTE_PUT(p,BS16_BOOTSIG,v) #define MBR_PUTBOOTSIG32(p,v) UBYTE_PUT(p,BS32_BOOTSIG,v) +#define PART_PUTTYPE(n,p,v) UBYTE_PUT(p,PART_ENTRY(n)+PART_TYPE,v) #define PART1_PUTTYPE(p,v) UBYTE_PUT(p,PART_ENTRY1+PART_TYPE,v) #define PART2_PUTTYPE(p,v) UBYTE_PUT(p,PART_ENTRY2+PART_TYPE,v) +#define PART3_PUTTYPE(p,v) UBYTE_PUT(p,PART_ENTRY3+PART_TYPE,v) +#define PART4_PUTTYPE(p,v) UBYTE_PUT(p,PART_ENTRY4+PART_TYPE,v) #define DIR_PUTATTRIBUTES(p,v) UBYTE_PUT(p,DIR_ATTRIBUTES,v) #define DIR_PUTNTRES(p,v) UBYTE_PUT(p,DIR_NTRES,v) @@ -378,10 +406,16 @@ #define MBR_GETVOLID16(p) fat_getuint32(UBYTE_PTR(p,BS16_VOLID)) #define MBR_GETVOLID32(p) fat_getuint32(UBYTE_PTR(p,BS32_VOLID)) +#define PART_GETSTARTSECTOR(n,p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY(n)+PART_STARTSECTOR)) +#define PART_GETSIZE(n,p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY(n)+PART_SIZE)) #define PART1_GETSTARTSECTOR(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY1+PART_STARTSECTOR)) #define PART1_GETSIZE(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY1+PART_SIZE)) #define PART2_GETSTARTSECTOR(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY2+PART_STARTSECTOR)) #define PART2_GETSIZE(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY2+PART_SIZE)) +#define PART3_GETSTARTSECTOR(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY3+PART_STARTSECTOR)) +#define PART3_GETSIZE(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY3+PART_SIZE)) +#define PART4_GETSTARTSECTOR(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY4+PART_STARTSECTOR)) +#define PART4_GETSIZE(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY4+PART_SIZE)) #define MBR_PUTBYTESPERSEC(p,v) fat_putuint16(UBYTE_PTR(p,BS_BYTESPERSEC),v) #define MBR_PUTROOTENTCNT(p,v) fat_putuint16(UBYTE_PTR(p,BS_ROOTENTCNT),v) @@ -389,10 +423,16 @@ #define MBR_PUTVOLID16(p,v) fat_putuint32(UBYTE_PTR(p,BS16_VOLID),v) #define MBR_PUTVOLID32(p,v) fat_putuint32(UBYTE_PTR(p,BS32_VOLID),v) +#define PART_PUTSTARTSECTOR(n,p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY(n)+PART_STARTSECTOR),v) +#define PART_PUTSIZE(n,p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY(n)+PART_SIZE),v) #define PART1_PUTSTARTSECTOR(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY1+PART_STARTSECTOR),v) #define PART1_PUTSIZE(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY1+PART_SIZE),v) #define PART2_PUTSTARTSECTOR(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY2+PART_STARTSECTOR),v) #define PART2_PUTSIZE(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY2+PART_SIZE),v) +#define PART3_PUTSTARTSECTOR(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY3+PART_STARTSECTOR),v) +#define PART3_PUTSIZE(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY3+PART_SIZE),v) +#define PART4_PUTSTARTSECTOR(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY4+PART_STARTSECTOR),v) +#define PART4_PUTSIZE(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY4+PART_SIZE),v) #ifdef CONFIG_FAT_LFN # define LDIR_PTRWCHAR1_5(p) UBYTE_PTR(p,LDIR_WCHAR1_5) diff --git a/nuttx/fs/fat/fs_fat32util.c b/nuttx/fs/fat/fs_fat32util.c index 5c402b468..12c2394f0 100644 --- a/nuttx/fs/fat/fs_fat32util.c +++ b/nuttx/fs/fat/fs_fat32util.c @@ -138,6 +138,10 @@ static int fat_checkbootrecord(struct fat_mountpt_s *fs) if (MBR_GETSIGNATURE(fs->fs_buffer) != BOOT_SIGNATURE16 || MBR_GETBYTESPERSEC(fs->fs_buffer) != fs->fs_hwsectorsize) { + fdbg("ERROR: Signature: %04x FS sectorsize: %d HW sectorsize: %d\n", + MBR_GETSIGNATURE(fs->fs_buffer), MBR_GETBYTESPERSEC(fs->fs_buffer), + fs->fs_hwsectorsize); + return -ENODEV; } @@ -172,6 +176,9 @@ static int fat_checkbootrecord(struct fat_mountpt_s *fs) if (!fs->fs_nfatsects || fs->fs_nfatsects >= fs->fs_hwnsectors) { + fdbg("ERROR: fs_nfatsects %d fs_hwnsectors: %d\n", + fs->fs_nfatsects, fs->fs_hwnsectors); + return -ENODEV; } @@ -189,6 +196,9 @@ static int fat_checkbootrecord(struct fat_mountpt_s *fs) if (!fs->fs_fattotsec || fs->fs_fattotsec > fs->fs_hwnsectors) { + fdbg("ERROR: fs_fattotsec %d fs_hwnsectors: %d\n", + fs->fs_fattotsec, fs->fs_hwnsectors); + return -ENODEV; } @@ -197,6 +207,9 @@ static int fat_checkbootrecord(struct fat_mountpt_s *fs) fs->fs_fatresvdseccount = MBR_GETRESVDSECCOUNT(fs->fs_buffer); if (fs->fs_fatresvdseccount > fs->fs_hwnsectors) { + fdbg("ERROR: fs_fatresvdseccount %d fs_hwnsectors: %d\n", + fs->fs_fatresvdseccount, fs->fs_hwnsectors); + return -ENODEV; } @@ -210,6 +223,9 @@ static int fat_checkbootrecord(struct fat_mountpt_s *fs) ndatasectors = fs->fs_fattotsec - fs->fs_fatresvdseccount - ntotalfatsects - rootdirsectors; if (ndatasectors > fs->fs_hwnsectors) { + fdbg("ERROR: ndatasectors %d fs_hwnsectors: %d\n", + ndatasectors, fs->fs_hwnsectors); + return -ENODEV; } @@ -235,11 +251,14 @@ static int fat_checkbootrecord(struct fat_mountpt_s *fs) } else if (!notfat32) { - fs->fs_fsinfo = fs->fs_fatbase + MBR_GETFSINFO(fs->fs_buffer); - fs->fs_type = FSTYPE_FAT32; + fs->fs_fsinfo = fs->fs_fatbase + MBR_GETFSINFO(fs->fs_buffer); + fs->fs_type = FSTYPE_FAT32; } else { + fdbg("ERROR: notfat32: %d fs_nclusters: %d\n", + notfat32, fs->fs_nclusters); + return -ENODEV; } @@ -550,37 +569,63 @@ int fat_mount(struct fat_mountpt_s *fs, bool writeable) /* The contents of sector 0 is not a boot record. It could be a * partition, however. Assume it is a partition and get the offset * into the partition table. This table is at offset MBR_TABLE and is - * indexed by 16x the partition number. Here we support only - * partition 0. - * - * Check if the partition exists and, if so, get the bootsector for that - * partition and see if we can find the boot record there. + * indexed by 16x the partition number. */ + + int i; + for (i = 0; i < 4; i++) + { + /* Check if the partition exists and, if so, get the bootsector for that + * partition and see if we can find the boot record there. + */ - if (PART1_GETTYPE(fs->fs_buffer) == 0) - { - fdbg("No MBR or partition\n"); - goto errout_with_buffer; - } + uint8_t part = PART_GETTYPE(i, fs->fs_buffer); + fvdbg("Partition %d, offset %d, type %d\n", i, PART_ENTRY(i), part); - /* There appears to be a partition, get the sector number of the - * partition (LBA) - */ + if (part == 0) + { + fvdbg("No partition %d\n", i); + continue; + } - fs->fs_fatbase = PART1_GETSTARTSECTOR(fs->fs_buffer); + /* There appears to be a partition, get the sector number of the + * partition (LBA) + */ - /* Read the new candidate boot sector */ + fs->fs_fatbase = PART_GETSTARTSECTOR(i, fs->fs_buffer); - ret = fat_hwread(fs, fs->fs_buffer, fs->fs_fatbase, 1); - if (ret < 0) - { - goto errout_with_buffer; - } + /* Read the new candidate boot sector */ - /* Check if this is a boot record */ + ret = fat_hwread(fs, fs->fs_buffer, fs->fs_fatbase, 1); + if (ret < 0) + { + /* Failed to read the sector */ - ret = fat_checkbootrecord(fs); - if (ret != OK) + goto errout_with_buffer; + } + + /* Check if this is a boot record */ + + ret = fat_checkbootrecord(fs); + if (ret == OK) + { + /* Break out of the loop if a valid boot record is found */ + + fvdbg("MBR found in partition %d\n", i); + break; + } + + /* Re-read sector 0 so that we can check the next partition */ + + fvdbg("Partition %d is not an MBR\n", i); + ret = fat_hwread(fs, fs->fs_buffer, 0, 1); + if (ret < 0) + { + goto errout_with_buffer; + } + } + + if (i > 3) { fdbg("No valid MBR\n"); goto errout_with_buffer; |