aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu Aleaxander <Aleaxander@gmail.com>2009-05-20 07:07:31 +0800
committerLiu Aleaxander <Aleaxander@gmail.com>2009-05-20 07:07:31 +0800
commit7ae9080b65998c402cee3268161035d7c7afa7cd (patch)
treee566fd73a3bf3b46893d6495797b0e4d4ecb67a2
parent88a72896dc32cc4a2a79b962af6b21ec5d442333 (diff)
downloaddevel-7ae9080b65998c402cee3268161035d7c7afa7cd.tar.gz
devel-7ae9080b65998c402cee3268161035d7c7afa7cd.tar.xz
devel-7ae9080b65998c402cee3268161035d7c7afa7cd.zip
Make the fat system dirve do the workldlinux
bug fixed; syslinux can read the files correctly , and more, it also can detect the fat cluster that corss one sector(FAT12 will, since the cache is based on sector size for fat filesystem), so it may or even can work correctly.
-rw-r--r--disklab.c7
-rw-r--r--ldlinux.c36
2 files changed, 33 insertions, 10 deletions
diff --git a/disklab.c b/disklab.c
index c0673ef..a30998f 100644
--- a/disklab.c
+++ b/disklab.c
@@ -21,7 +21,8 @@ void* getoneblk(__u32 block)
buf = malloc(blk_size);
if ( (bytes_read = read(fd, buf, blk_size)) < blk_size )
- printf("read %d bytes less than %dB..\n", bytes_read, blk_size);
+ printf("%s:%s: read %d bytes less than %dB..\n",
+ __FILE__, __FUNCTION__, bytes_read, blk_size);
return buf;
}
@@ -37,7 +38,7 @@ void getlinsec(char *buf, int sector, int sector_cnt)
}
if ( (bytes_read = read(fd, buf, 512*sector_cnt)) < 512*sector_cnt)
- printf("read %d bytes less than %d bytes..\n",
- bytes_read, 512 * sector_cnt);
+ printf("%s:%s: read %d bytes less than %d bytes..\n",
+ __FILE__, __FUNCTION__, bytes_read, 512 * sector_cnt);
}
diff --git a/ldlinux.c b/ldlinux.c
index 8e697fb..4e4f776 100644
--- a/ldlinux.c
+++ b/ldlinux.c
@@ -171,12 +171,31 @@ __u32 nextcluster(__u32 clust_num)
__u32 next_cluster;
__u32 fat_sector;
struct cache_struct *cs;
+
+#if FATType == FAT12
+ int offset;
+ int lo, hi;
+#endif
switch(FATType) {
case FAT12:
fat_sector = (clust_num + clust_num / 2) >> SECTOR_SHIFT;
cs = getfatsector(fat_sector);
- next_cluster = *(__u16 *)(cs->data + (clust_num*3/2) % 512);
+ offset = (clust_num * 3 / 2) & ( SECTOR_SIZE -1 );
+ if ( offset == 0x1ff ) {
+ /*
+ * we got the end of the one fat sector,
+ * but we don't got we have(just one byte, we need two),
+ * so store the low part, then read the next fat
+ * sector, read the high part, then combine it.
+ */
+ lo = *(__u8 *)(cs->data + offset);
+ cs = getfatsector(fat_sector + 1);
+ hi = *(__u8 *)cs->data;
+ next_cluster = (hi << 8) + lo;
+ } else
+ next_cluster = *(__u16 *)(cs->data + offset);
+
if ( clust_num & 0x0001 )
next_cluster >>= 4; /* cluster number is ODD */
else
@@ -261,12 +280,13 @@ __u32 nextsector(__u32 sector)
* 64K boundaries.
*
* @param: buf
- * @param: curr_sector, the sector where to start reading
+ * @param: file structure
* @param: sectors
*
*/
-void __getfssec(char *buf, __u32 curr_sector, __u32 sectors)
+void __getfssec(char *buf, struct open_file_t *file, __u32 sectors)
{
+ __u32 curr_sector = file->file_sector;
__u32 frag_start , next_sector;
__u32 con_sec_cnt;
@@ -301,8 +321,11 @@ void __getfssec(char *buf, __u32 curr_sector, __u32 sectors)
if ( !sectors )
break;
//curr_sector --; /* this is the last sector actually read */
- curr_sector = next_sector = nextsector(curr_sector);
+ curr_sector = next_sector;
}while( sectors );
+
+ /* update the file_sector filed for the next read */
+ file->file_sector = nextsector(curr_sector);
}
@@ -329,7 +352,7 @@ __u32 getfssec(char *buf, struct open_file_t *file, __u32 sectors, int *have_mor
if ( sectors > file->file_left )
sectors = file->file_left;
- __getfssec(buf, file->file_sector, sectors);
+ __getfssec(buf, file, sectors);
if ( bytes_read >= file->file_bytesleft ) {
bytes_read = file->file_bytesleft;
@@ -343,8 +366,7 @@ __u32 getfssec(char *buf, struct open_file_t *file, __u32 sectors, int *have_mor
}
file->file_left -= sectors;
- file->file_sector += sectors;
-
+
return bytes_read;
}