Dear Remy, I have checked patches and I think there are OK.
Also, I have aplied [patch 1/2] and [patch 2/2] on git u-boot version. Then I have copied patched files (fat.h and fat.c) on our customized u-boot-1.1.6 version. Finally I have built and installed u-boot on our custom board. I have executed fatls and fatload commands with our 2048 bytes sector USB pendrive and IT WORKS !!!! Thanks a lot for your help. El jue, 27-11-2008 a las 22:30 +0100, Remy Bohmer escribió: > documento de texto sencillo adjunto > (fat-on-non-standard-sector-size-devices.patch) > The patch below is a patch originally posted by Igor Luri. > However, the patch posted on the mailinglist was not readable (base64) > and thus not mergable or testable. Also tabs/spaces were malformed. > > So, I merged the whole patch by hand and posted it again. > > Igor can you please check if I did this cleanup properly. > > Notice that the code that is being modified here does not match _any_ > coding rule standard and is actually a big mess. So, I did not focus > on the Coding Rules too much for this patch. > I will post a seperate patch to fix this for the complete files also. > ---------------- > There are USB devices with sector size different than 512 bytes. In > fact, I have one with 2048 bytes per sector: > > scsi0 : SCSI emulation for USB Mass Storage devices > Vendor: ChipsBnk Model: Flash Disk Rev: 4.00 > Type: Direct-Access ANSI SCSI revision: 02 > Attached scsi removable disk sda at scsi0, channel 0, id 0, lun 0 > SCSI device sda: 129124 2048-byte hdwr sectors (264 MB) > sda: Write Protect is off > Partition check: > sda: sda1 sda2 sda3 sda4 > > U-boot FAT filesystem code supposes that sector size is always 512 > bytes, consecuently fatload and fatls commands ends up with a > segmentation fault. > > Attached patches adds FAT support on devices with sector size up to 8192 > bytes. > > Signed-off-by: Igor Luri <[EMAIL PROTECTED]> > Signed-off-by: Remy Bohmer <[EMAIL PROTECTED]> > --- > fs/fat/fat.c | 89 > ++++++++++++++++++++++++++++++++++++++++------------------ > include/fat.h | 18 +++-------- > 2 files changed, 68 insertions(+), 39 deletions(-) > > Index: u-boot-usb.new/fs/fat/fat.c > =================================================================== > --- u-boot-usb.new.orig/fs/fat/fat.c 2008-11-27 21:40:25.000000000 +0100 > +++ u-boot-usb.new/fs/fat/fat.c 2008-11-27 22:10:40.000000000 +0100 > @@ -30,6 +30,7 @@ > #include <fat.h> > #include <asm/byteorder.h> > #include <part.h> > +#include <malloc.h> > > /* > * Convert a string to lowercase. > @@ -67,12 +68,17 @@ int disk_read (__u32 startblock, __u32 g > int > fat_register_device(block_dev_desc_t *dev_desc, int part_no) > { > - unsigned char buffer[SECTOR_SIZE]; > + unsigned char *buffer; > disk_partition_t info; > > if (!dev_desc->block_read) > return -1; > cur_dev = dev_desc; > + > + buffer = malloc(cur_dev->blksz); > + if (!buffer) > + return -1; > + > /* check if we have a MBR (on floppies we have only a PBR) */ > if (dev_desc->block_read (dev_desc->dev, 0, 1, (ulong *) buffer) != 1) { > printf ("** Can't read from device %d **\n", dev_desc->dev); > @@ -118,6 +124,7 @@ fat_register_device(block_dev_desc_t *de > cur_part = 1; > } > #endif > + free(buffer); > return 0; > } > > @@ -220,12 +227,12 @@ get_fatent(fsdata *mydata, __u32 entry) > > /* Read a new block of FAT entries into the cache. */ > if (bufnum != mydata->fatbufnum) { > - int getsize = FATBUFSIZE/FS_BLOCK_SIZE; > + int getsize = FATBUFSIZE / mydata->sector_size; > __u8 *bufptr = mydata->fatbuf; > __u32 fatlength = mydata->fatlength; > __u32 startblock = bufnum * FATBUFBLOCKS; > > - fatlength *= SECTOR_SIZE; /* We want it in bytes now */ > + fatlength *= mydata->sector_size; /* We want it in bytes now */ > startblock += mydata->fat_sect; /* Offset from start of disk */ > > if (getsize > fatlength) getsize = fatlength; > @@ -300,20 +307,25 @@ get_cluster(fsdata *mydata, __u32 clustn > } > > FAT_DPRINT("gc - clustnum: %d, startsect: %d\n", clustnum, startsect); > - if (disk_read(startsect, size/FS_BLOCK_SIZE , buffer) < 0) { > + if (disk_read(startsect, size / mydata->sector_size, buffer) < 0) { > FAT_DPRINT("Error reading data\n"); > return -1; > } > - if(size % FS_BLOCK_SIZE) { > - __u8 tmpbuf[FS_BLOCK_SIZE]; > - idx= size/FS_BLOCK_SIZE; > + if (size % mydata->sector_size) { > + __u8 *tmpbuf; > + > + tmpbuf = (__u8 *) malloc(mydata->sector_size); > + if (!tmpbuf) > + return -1; > + idx = size / mydata->sector_size; > if (disk_read(startsect + idx, 1, tmpbuf) < 0) { > FAT_DPRINT("Error reading data\n"); > return -1; > } > - buffer += idx*FS_BLOCK_SIZE; > + buffer += idx * mydata->sector_size; > > - memcpy(buffer, tmpbuf, size % FS_BLOCK_SIZE); > + memcpy(buffer, tmpbuf, size % mydata->sector_size); > + free(tmpbuf); > return 0; > } > > @@ -331,7 +343,7 @@ get_contents(fsdata *mydata, dir_entry * > unsigned long maxsize) > { > unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0; > - unsigned int bytesperclust = mydata->clust_size * SECTOR_SIZE; > + unsigned int bytesperclust = mydata->clust_size * mydata->sector_size; > __u32 curclust = START(dentptr); > __u32 endclust, newclust; > unsigned long actsize; > @@ -440,7 +452,8 @@ get_vfatname(fsdata *mydata, int curclus > { > dir_entry *realdent; > dir_slot *slotptr = (dir_slot*) retdent; > - __u8 *nextclust = cluster + mydata->clust_size * SECTOR_SIZE; > + __u8 *nextclust = cluster + > + mydata->clust_size * mydata->sector_size; > __u8 counter = (slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff; > int idx = 0; > > @@ -463,7 +476,7 @@ get_vfatname(fsdata *mydata, int curclus > return -1; > } > if (get_cluster(mydata, curclust, get_vfatname_block, > - mydata->clust_size * SECTOR_SIZE) != 0) { > + mydata->clust_size * mydata->sector_size) != 0) { > FAT_DPRINT("Error: reading directory block\n"); > return -1; > } > @@ -533,8 +546,8 @@ static dir_entry *get_dentfromdir (fsdat > dir_entry *dentptr; > int i; > > - if (get_cluster (mydata, curclust, get_dentfromdir_block, > - mydata->clust_size * SECTOR_SIZE) != 0) { > + if (get_cluster(mydata, curclust, get_dentfromdir_block, > + mydata->clust_size * mydata->sector_size) != 0) { > FAT_DPRINT ("Error: reading directory block\n"); > return NULL; > } > @@ -667,9 +680,16 @@ static dir_entry *get_dentfromdir (fsdat > static int > read_bootsectandvi(boot_sector *bs, volume_info *volinfo, int *fatsize) > { > - __u8 block[FS_BLOCK_SIZE]; > + __u8 *block; > volume_info *vistart; > > + if (!cur_dev) > + return -1; > + > + block = (__u8 *)malloc(cur_dev->blksz); > + if (!block) > + return -1; > + > if (disk_read(0, 1, block) < 0) { > FAT_DPRINT("Error: reading block\n"); > return -1; > @@ -680,6 +700,7 @@ read_bootsectandvi(boot_sector *bs, volu > bs->fat_length = FAT2CPU16(bs->fat_length); > bs->secs_track = FAT2CPU16(bs->secs_track); > bs->heads = FAT2CPU16(bs->heads); > + *(__u16 *)bs->sector_size = FAT2CPU16(*(__u16 *)bs->sector_size); > #if 0 /* UNUSED */ > bs->hidden = FAT2CPU32(bs->hidden); > #endif > @@ -704,7 +725,7 @@ read_bootsectandvi(boot_sector *bs, volu > /* Terminate fs_type string. Writing past the end of vistart > is ok - it's just the buffer. */ > vistart->fs_type[8] = '\0'; > - > + free(block); > if (*fatsize == 32) { > if (compare_sign(FAT32_SIGN, vistart->fs_type) == 0) { > return 0; > @@ -757,6 +778,7 @@ do_fat_read (const char *filename, void > mydata->fatlength = bs.fat_length; > } > mydata->fat_sect = bs.reserved; > + mydata->sector_size = *(__u16 *)bs.sector_size; > cursect = mydata->rootdir_sect > = mydata->fat_sect + mydata->fatlength * bs.fats; > mydata->clust_size = bs.cluster_size; > @@ -766,17 +788,21 @@ do_fat_read (const char *filename, void > - (mydata->clust_size * 2); > } else { > rootdir_size = ((bs.dir_entries[1] * (int) 256 + bs.dir_entries[0]) > - * sizeof (dir_entry)) / SECTOR_SIZE; > + * sizeof (dir_entry)) / mydata->sector_size; > mydata->data_begin = mydata->rootdir_sect + rootdir_size > - (mydata->clust_size * 2); > } > mydata->fatbufnum = -1; > + mydata->fatbuf = (__u8 *) malloc(FATBUFSIZE); > + if (!mydata->fatbuf) > + return -1; > > FAT_DPRINT ("FAT%d, fatlength: %d\n", mydata->fatsize, > mydata->fatlength); > FAT_DPRINT ("Rootdir begins at sector: %d, offset: %x, size: %d\n" > "Data begins at: %d\n", > - mydata->rootdir_sect, mydata->rootdir_sect * SECTOR_SIZE, > + mydata->rootdir_sect, > + mydata->rootdir_sect * mydata->sector_size, > rootdir_size, mydata->data_begin); > FAT_DPRINT ("Cluster size: %d\n", mydata->clust_size); > > @@ -787,8 +813,10 @@ do_fat_read (const char *filename, void > strcpy (fnamecopy, filename); > downcase (fnamecopy); > if (*fnamecopy == '\0') { > - if (!dols) > - return -1; > + if (!dols) { > + free(mydata->fatbuf); > + return -1; > + } > dols = LS_ROOT; > } else if ((idx = dirdelim (fnamecopy)) >= 0) { > isdir = 1; > @@ -805,8 +833,9 @@ do_fat_read (const char *filename, void > int i; > > if (disk_read (cursect, mydata->clust_size, do_fat_read_block) < 0) { > - FAT_DPRINT ("Error: reading rootdir block\n"); > - return -1; > + FAT_DPRINT ("Error: reading rootdir block\n"); > + free(mydata->fatbuf); > + return -1; > } > dentptr = (dir_entry *) do_fat_read_block; > for (i = 0; i < DIRENTSPERBLOCK; i++) { > @@ -856,6 +885,7 @@ do_fat_read (const char *filename, void > continue; > } > } else if (dentptr->name[0] == 0) { > + free(mydata->fatbuf); > FAT_DPRINT ("RootDentname == NULL - %d\n", i); > if (dols == LS_ROOT) { > printf ("\n%d file(s), %d dir(s)\n\n", files, dirs); > @@ -906,9 +936,10 @@ do_fat_read (const char *filename, void > dentptr++; > continue; > } > - if (isdir && !(dentptr->attr & ATTR_DIR)) > + if (isdir && !(dentptr->attr & ATTR_DIR)) { > + free(mydata->fatbuf); > return -1; > - > + } > FAT_DPRINT ("RootName: %s", s_name); > FAT_DPRINT (", start: 0x%x", START (dentptr)); > FAT_DPRINT (", size: 0x%x %s\n", > @@ -949,20 +980,24 @@ do_fat_read (const char *filename, void > > if (get_dentfromdir (mydata, startsect, subname, dentptr, > isdir ? 0 : dols) == NULL) { > + free(mydata->fatbuf); > if (dols && !isdir) > return 0; > return -1; > } > > if (idx >= 0) { > - if (!(dentptr->attr & ATTR_DIR)) > - return -1; > - subname = nextname; > + if (!(dentptr->attr & ATTR_DIR)) { > + free(mydata->fatbuf); > + return -1; > + } > + subname = nextname; > } > } > ret = get_contents (mydata, dentptr, buffer, maxsize); > FAT_DPRINT ("Size: %d, got: %ld\n", FAT2CPU32 (dentptr->size), ret); > > + free(mydata->fatbuf); > return ret; > } > > Index: u-boot-usb.new/include/fat.h > =================================================================== > --- u-boot-usb.new.orig/include/fat.h 2008-11-27 21:40:17.000000000 +0100 > +++ u-boot-usb.new/include/fat.h 2008-11-27 21:45:13.000000000 +0100 > @@ -31,20 +31,13 @@ > > #define CONFIG_SUPPORT_VFAT > > -#define SECTOR_SIZE FS_BLOCK_SIZE > - > -#define FS_BLOCK_SIZE 512 > - > -#if FS_BLOCK_SIZE != SECTOR_SIZE > -#error FS_BLOCK_SIZE != SECTOR_SIZE - This code needs to be fixed! > -#endif > - > #define MAX_CLUSTSIZE 65536 > -#define DIRENTSPERBLOCK (FS_BLOCK_SIZE/sizeof(dir_entry)) > -#define DIRENTSPERCLUST > ((mydata->clust_size*SECTOR_SIZE)/sizeof(dir_entry)) > +#define DIRENTSPERBLOCK (mydata->sector_size / sizeof(dir_entry)) > +#define DIRENTSPERCLUST ((mydata->clust_size * mydata->sector_size) / \ > + sizeof(dir_entry)) > > #define FATBUFBLOCKS 6 > -#define FATBUFSIZE (FS_BLOCK_SIZE*FATBUFBLOCKS) > +#define FATBUFSIZE (mydata->sector_size * FATBUFBLOCKS) > #define FAT12BUFSIZE ((FATBUFSIZE*2)/3) > #define FAT16BUFSIZE (FATBUFSIZE/2) > #define FAT32BUFSIZE (FATBUFSIZE/4) > @@ -182,8 +175,9 @@ typedef struct dir_slot { > * (see FAT32 accesses) > */ > typedef struct { > - __u8 fatbuf[FATBUFSIZE]; /* Current FAT buffer */ > + __u8 *fatbuf; /* Current FAT buffer */ > int fatsize; /* Size of FAT in bits */ > + __u16 sector_size; /* Sector size */ > __u16 fatlength; /* Length of FAT in sectors */ > __u16 fat_sect; /* Starting sector of the FAT */ > __u16 rootdir_sect; /* Start sector of root directory */ > -- Igor Luri R&D Software Department Fagor Aotek S. Coop. P. O. Box 144 E-20500 Mondragón-Arrasate Tel. ++34 943 71 92 00 ++34 943 71 92 01 (Ext. 44268) Fax. ++34 943 79 92 03 www.aotek.es _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot