aboutsummaryrefslogtreecommitdiffstats
path: root/ldlinux.c
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 /ldlinux.c
parent88a72896dc32cc4a2a79b962af6b21ec5d442333 (diff)
downloaddevel-ldlinux.tar.gz
devel-ldlinux.tar.xz
devel-ldlinux.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.
Diffstat (limited to 'ldlinux.c')
-rw-r--r--ldlinux.c36
1 files changed, 29 insertions, 7 deletions
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;
}