For the past couple of days, I've been trying to get the Rockbox
bootloader working on my 5.5G iPod Video. I've managed to get it to the
point where it reads the checksum and model name from rockbox.ipod, but
then it hangs somewhere in ata_read_sectors() while reading the rest of
the image. I haven't modified ata.c at all, and I don't see why it
should crash in there -- not that I really understand the function.

The problem this patch addresses is that while the hard drive has normal
512-byte sectors, the filesystem has a logical sector size of 2048
bytes. It's presented over USB as a 2048-byte-per-sector HDD, so I can't
just reformat the partition with a sane setting. Heavens, how I would
_like_ to.

All the patch does is quadruple the numbers read in the partition table,
quadruple the number and addresses of sectors read and written by the
FAT code, and make bpb_is_sane() expect 2048-byte sectors. I haven't
quite finished doing that -- the fsinfo accesses are untouched, at the
least. But, again, I don't see what I've done that would lead to a crash
in ata_read_sectors(). I can't help but feel that I've done something
foolish.

-- Rob
diff -Naur rockbox-devel/firmware/common/disk.c rockbox-dirty/firmware/common/disk.c
--- rockbox-devel/firmware/common/disk.c	2006-08-31 19:19:35.000000000 +0000
+++ rockbox-dirty/firmware/common/disk.c	2006-09-23 22:16:07.000000000 +0000
@@ -78,6 +78,10 @@
         pinfo[i].type  = ptr[4];
         pinfo[i].start = BYTES2INT32(ptr, 8);
         pinfo[i].size  = BYTES2INT32(ptr, 12);
+#ifdef FAT_2K_SECTORS
+        pinfo[i].start *= 4;
+        pinfo[i].size *= 4;
+#endif
 
         DEBUGF("Part%d: Type %02x, start: %08lx size: %08lx\n",
                i,pinfo[i].type,pinfo[i].start,pinfo[i].size);
diff -Naur rockbox-devel/firmware/drivers/fat.c rockbox-dirty/firmware/drivers/fat.c
--- rockbox-devel/firmware/drivers/fat.c	2006-08-02 15:58:02.000000000 +0000
+++ rockbox-dirty/firmware/drivers/fat.c	2006-09-23 22:01:15.000000000 +0000
@@ -506,12 +506,23 @@
 #ifndef HAVE_MULTIVOLUME
     struct bpb* fat_bpb = &fat_bpbs[0];
 #endif
+#ifdef FAT_2K_SECTORS
+#warning PATCHED
+    if(fat_bpb->bpb_bytspersec != 2048)
+    {
+        DEBUGF( "bpb_is_sane() - Error: sector size is not 2048 (%d)\n",
+                fat_bpb->bpb_bytspersec);
+        return -1;
+    }
+#else
+#warning NOT PATCHED
     if(fat_bpb->bpb_bytspersec != 512)
     {
         DEBUGF( "bpb_is_sane() - Error: sector size is not 512 (%d)\n",
                 fat_bpb->bpb_bytspersec);
         return -1;
     }
+#endif
     if((long)fat_bpb->bpb_secperclus * (long)fat_bpb->bpb_bytspersec > 128L*1024L)
     {
         DEBUGF( "bpb_is_sane() - Error: cluster size is larger than 128K "
@@ -564,9 +575,16 @@
 #endif
 
     /* Write to the first FAT */
+#ifdef FAT_2K_SECTORS
+    rc = ata_write_sectors(IF_MV2(fce->fat_vol->drive,)
+                           secnum * 4, 4,
+                           sectorbuf);
+#else
     rc = ata_write_sectors(IF_MV2(fce->fat_vol->drive,)
                            secnum, 1,
                            sectorbuf);
+#endif
+
     if(rc < 0)
     {
         panicf("flush_fat_sector() - Could not write sector %ld"
@@ -585,8 +603,13 @@
 #else
         secnum += fat_bpbs[0].fatsize;
 #endif
+#ifdef FAT_2K_SECTORS
+        rc = ata_write_sectors(IF_MV2(fce->fat_vol->drive,)
+                               secnum * 4, 4, sectorbuf);
+#else
         rc = ata_write_sectors(IF_MV2(fce->fat_vol->drive,)
                                secnum, 1, sectorbuf);
+#endif
         if(rc < 0)
         {
             panicf("flush_fat_sector() - Could not write sector %ld"
@@ -631,9 +654,15 @@
     /* Load the sector if it is not cached */
     if(!fce->inuse)
     {
+#ifdef FAT_2K_SECTORS
+        rc = ata_read_sectors(IF_MV2(fat_bpb->drive,)
+                              (secnum * 4) + fat_bpb->startsector,4,
+                              sectorbuf);
+#else
         rc = ata_read_sectors(IF_MV2(fat_bpb->drive,)
                               secnum + fat_bpb->startsector,1,
                               sectorbuf);
+#endif
         if(rc < 0)
         {
             DEBUGF( "cache_fat_sector() - Could not read sector %ld"
@@ -1933,6 +1962,11 @@
     struct bpb* fat_bpb = &fat_bpbs[0];
 #endif
     int rc;
+    
+#ifdef FAT_2K_SECTORS
+    start *= 4;
+    count *= 4;
+#endif
 
     LDEBUGF("transfer(s=%lx, c=%lx, %s)\n",
         start+ fat_bpb->startsector, count, write?"write":"read");
diff -Naur rockbox-devel/firmware/export/fat.h rockbox-dirty/firmware/export/fat.h
--- rockbox-devel/firmware/export/fat.h	2006-07-31 22:59:45.000000000 +0000
+++ rockbox-dirty/firmware/export/fat.h	2006-09-23 21:41:53.000000000 +0000
@@ -22,8 +22,13 @@
 
 #include <stdbool.h>
 #include "ata.h" /* for volume definitions */
+#include "config.h" /* for FAT_2K_SECTORS or not */
 
+#ifdef FAT_2K_SECTORS
+#define SECTOR_SIZE 2048
+#else
 #define SECTOR_SIZE 512
+#endif
 
 /* Number of bytes reserved for a file name (including the trailing \0).
    Since names are stored in the entry as UTF-8, we won't be able to

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to