[U-Boot] [patch 2/2] Cleanup patch Fat on non standard sector sizedevices

Igor Luri iluri at aotek.es
Fri Nov 28 12:09:04 CET 2008


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 <iluri at aotek.es>
> Signed-off-by: Remy Bohmer <linux at bohmer.net>
> ---
>  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


More information about the U-Boot mailing list