Message ID | 1365522374-30237-1-git-send-email-egbert.eich@gmail.com |
---|---|
State | Accepted |
Delegated to: | Tom Rini |
Headers | show |
On Tue, Apr 09, 2013 at 05:46:14AM -0000, egbert.eich@gmail.com wrote: > From: Egbert Eich <eich@suse.com> > > Devices that used to have a whole disk FAT filesystem but got then > partitioned will most likely still have a FAT or FAT32 signature > in the first sector as this sector does not get overwritten by > a partitioning tool (otherwise the tool would risk to kill the mbr). > > The current partition search algorithm will erronously detects such > a device as a raw FAT device. > > Instead of looking for the FAT or FAT32 signatures immediately we > use the same algorithm as used by the Linux kernel and first check > for a valid boot indicator flag on each of the 4 partitions. > If the value of this flag is invalid for the first entry we then > do the raw partition check. > If the flag for any higher partition is wrong we assume the device > is neiter a MBR nor PBR device. > > Signed-off-by: Egbert Eich <eich@suse.com> Applied to u-boot/master, thanks!
diff --git a/disk/part_dos.c b/disk/part_dos.c index 37087a6..ab984cd 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -74,13 +74,26 @@ static void print_one_part(dos_partition_t *p, int ext_part_sector, static int test_block_type(unsigned char *buffer) { + int slot; + struct dos_partition *p; + if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) || (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) { return (-1); } /* no DOS Signature at all */ - if (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET],"FAT",3)==0 || - strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET],"FAT32",5)==0) { - return DOS_PBR; /* is PBR */ + p = (struct dos_partition *)&buffer[DOS_PART_TBL_OFFSET]; + for (slot = 0; slot < 3; slot++) { + if (p->boot_ind != 0 && p->boot_ind != 0x80) { + if (!slot && + (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET], + "FAT", 3) == 0 || + strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET], + "FAT32", 5) == 0)) { + return DOS_PBR; /* is PBR */ + } else { + return -1; + } + } } return DOS_MBR; /* Is MBR */ }